# Why does getElementById return null and break innerHTML in my script?

Source: https://coursesweb.net/forum/t/why-does-getelementbyid-return-null-and-break-innerhtml-in-my-script/
Site: CoursesWeb Forum, category Error Messages Explained
Published: 2026-11-12. Updated: 2026-11-12. Replies: 0.

## Question by Teodora Vance (staff), 2026-11-12

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.

## 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:

```html
<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 `defer` attribute:

```html
<head>
  <script src="app.js" defer></script>
</head>
<body>
  <p id="result"></p>
</body>
```

```js
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](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) says it returns the element whose id matches, or `null` if 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](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script) says the `defer` attribute tells the browser the script is meant to run after the document has been parsed, but before the `DOMContentLoaded` event fires. Deferred scripts also run in the order they appear. Two important details from the same page: `defer` has no effect without a `src` attribute, 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:

```js
document.addEventListener("DOMContentLoaded", () => {
  const result = document.getElementById("result");
  result.textContent = "Hello";
});
```

I used `textContent` in these examples because it sets plain text. `innerHTML` makes 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()](https://coursesweb.net/javascript/getelementbyid) walks through more examples.

## Mistakes beginners make

1. **Wrong capital letters.** The id is case-sensitive. MDN's example: `getElementById("Main")` returns `null` for `<div id="main">`. The method name matters too: it is `getElementById`, and MDN states that `getElementByID` is not valid.
2. **Calling it on an element instead of document.** `getElementById` only exists on `document`. Writing `parent.getElementById("x")` throws "is not a function". If you want to search inside one element, use `parent.querySelector("#x")`.
3. **Creating an element but never inserting it.** MDN's example shows that after `createElement` and setting `id`, `getElementById` still returns `null` until you add the element to the page with something like `append` or `insertBefore`.
4. **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

1. Open the browser console (F12) and type `document.getElementById("result")`. Element or `null`?
2. If it is `null`, view the page source and search for the id. Copy it character by character, including capitals.
3. Is the id attribute on the element, with `id="result"` and not `class="result"` or `name="result"`?
4. Is your script above the element? Add `defer` to an external script, or move it to the end of the body.
5. Does the element appear only after a click or a fetch? Then the lookup must run after that step, not at load time.
6. Is the page in an iframe, or does the element live in a different page? `document` only sees its own page.

---
Cite as: 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.
