Why does getElementById return null and break innerHTML in my script?
getElementById returns null when no element with that exact id exists in the page at the moment the line runs. The usual cause is a script that runs before the browser has read the element, or a typo in the id. Move the script so it runs after the page is parsed, then check the spelling.
Cite
CoursesWeb Forum, "Why does getElementById return null and break innerHTML in my script?", https://coursesweb.net/forum/t/why-does-getelementbyid-return-null-and-break-innerhtml-in-my-script/, accessed 2026-11-12.- Teodora VanceStaffModerator: HTML, CSS and front end JavaScript ·
The error you are seeing
Setting innerHTML on a missing element gives an error like this in Chrome:
Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')Firefox words it differently, but both mean the same thing: the left side of your assignment is
null, not an element. The bug is not in innerHTML. It is one step earlier, in the lookup.A minimal example that fails, and the fix
This version fails because the script sits in the head, before the paragraph exists:
<head> <script> document.getElementById("result").innerHTML = "Hello"; </script> </head> <body> <p id="result"></p> </body>The browser reads the page from top to bottom. When it runs that script,
<p id="result">has not been parsed yet.The fix is to put the code in its own file and load it with the
deferattribute:<head> <script src="app.js" defer></script> </head> <body> <p id="result"></p> </body>const result = document.getElementById("result"); if (result) { result.textContent = "Hello"; }Now the script waits until the document has been parsed. The
if (result)check is a safety net: if the id is ever wrong, your script skips that step instead of crashing the rest of the file.Why this works
MDN's getElementById page says it returns the element whose id matches, or
nullif no matching element was found in the document. Nothing more is going on. The method does not wait, and it does not search for the element later.On timing, MDN's script element page says the
deferattribute tells the browser the script is meant to run after the document has been parsed, but before theDOMContentLoadedevent fires. Deferred scripts also run in the order they appear. Two important details from the same page:deferhas no effect without asrcattribute, so it does nothing on an inline script like the first example, and module scripts (type="module") defer by default.You have two other options if you cannot use
defer. Put the script tag at the very end of the body, immediately before the closing body tag. Or wrap your code in a listener:document.addEventListener("DOMContentLoaded", () => { const result = document.getElementById("result"); result.textContent = "Hello"; });I used
textContentin these examples because it sets plain text.innerHTMLmakes the browser parse your string as HTML, which is what you want for markup you wrote yourself, but not for text a visitor typed.Our tutorial on document.getElementById() walks through more examples.
Mistakes beginners make
- Wrong capital letters. The id is case-sensitive. MDN's example:
getElementById("Main")returnsnullfor<div id="main">. The method name matters too: it isgetElementById, and MDN states thatgetElementByIDis not valid. - Calling it on an element instead of document.
getElementByIdonly exists ondocument. Writingparent.getElementById("x")throws "is not a function". If you want to search inside one element, useparent.querySelector("#x"). - Creating an element but never inserting it. MDN's example shows that after
createElementand settingid,getElementByIdstill returnsnulluntil you add the element to the page with something likeappendorinsertBefore. - Duplicate ids. MDN notes that when two elements share an id, you get the first one. That may not be the one you meant.
Check this in order
- Open the browser console (F12) and type
document.getElementById("result"). Element ornull? - If it is
null, view the page source and search for the id. Copy it character by character, including capitals. - Is the id attribute on the element, with
id="result"and notclass="result"orname="result"? - Is your script above the element? Add
deferto an external script, or move it to the end of the body. - Does the element appear only after a click or a fetch? Then the lookup must run after that step, not at load time.
- Is the page in an iframe, or does the element live in a different page?
documentonly sees its own page.
- Wrong capital letters. The id is case-sensitive. MDN's example:
Write something first.
Give people something to work with: at least 30 words on what happened and what you tried.
That is too long. Keep it under 6,000 characters.
Write the question as the title, 15 to 140 characters, no links.
Pick a category.
Add a name (2 to 40 characters, no links).
That email address does not look right.
That was quick. Read the thread, then try again.
The form expired. Reload the page and post again.
Something went wrong with the form. Reload and try again.
Please complete the check and post again.
Limit reached for now. Try again later.
This thread is closed to new replies.
This thread no longer accepts replies.
Something went wrong with the form. Reload and try again.
Post a reply or question first (name and email), then this browser can vote, edit and accept answers.
You cannot vote on your own post.
Only the author (within 30 days) or the forum team can do that.
That email already has an account. Use your sign-in link instead.
New accounts are paused for the moment. Try again later.
That was already posted.