Uncaught TypeError: Cannot read properties of null, explained and fixed

This error means JavaScript tried to read a property off a value that is null. Null is not an accident of timing in the way undefined usually is, something set this value to nothing on purpose, or a lookup that returns null by design found no match. The overwhelmingly common case on web pages: document.getElementById() or querySelector() found no element and returned null, and the very next property access threw.

How to find the null

  1. Read the end of the message. (reading 'addEventListener') or (reading 'value') after a DOM lookup is the classic fingerprint of a missing element.
  2. Click the top stack frame and identify the expression before the dot, then log the base value and, for DOM code, log the selector or id being searched for.
  3. Run the same lookup in the console on the live page: document.getElementById('the-id'). If it returns null there too, the element genuinely is not in the page at that moment.

The usual causes, most common first

  1. The script ran before the element existed. A script in the document head executes before the body is parsed, so every lookup misses. This is the number one cause.
  2. A wrong id or selector, a typo, an id renamed in the HTML but not in the script, or a class selector used where an id was meant.
  3. The element is rendered conditionally by a framework and is absent in the state where the code runs, logged out versus logged in, empty list versus populated list.
  4. State initialized as null and read too early: useState(null) fetched data, a ref that has not attached yet (ref.current is null before mount and after unmount).
  5. A JSON field that is genuinely null, the API uses null for “no value” and the code assumed an object would always be there.

The fixes, in order

  1. Let the DOM exist first: move the script to the end of the body, add the defer attribute, or wrap setup code in a DOMContentLoaded listener. One of these fixes most occurrences outright.
  2. Make the selector match reality: compare the id in the script character by character with the HTML, and remember getElementById takes no # while querySelector requires it.
  3. Check before use when absence is possible: const el = document.querySelector(sel); if (el) { ... }. Treat a null lookup as a normal outcome, not an impossibility.
  4. For framework state, model the empty phase: render a loading or empty state while the value is null instead of dereferencing it, and only attach ref-based logic after mount.
Null and undefined are different clues. Undefined usually means “never set”. Null usually means “set to nothing deliberately”, an empty lookup result, a cleared field, a JSON null. Asking “who set this to null, or which lookup returned it” finds the cause faster than asking “why is this missing”.

Common questions

Why does getElementById return null when the element is right there in the HTML? Timing, almost always. The script executed before the parser reached that element, typically a script tag in the head without defer. View-source shows the final document, not the document as it existed when the script ran.

What is the difference between this and “cannot read properties of undefined”? The shape of the bug is identical, only the empty value differs. Null points at deliberate emptiness or failed lookups, undefined points at values that were never assigned. The distinction often identifies the culprit in one step.

Does optional chaining fix it? user?.name stops the throw, but if the element or object was supposed to exist, the feature then silently does nothing. Guard where absence is legitimate, fix the lookup or the timing where it is not.

Related errors

Cannot read properties of undefined · Cannot read properties of null, the data side · TypeError: is not a function