Skip to content
beginner

Fix "Cannot Read Properties of null" in JavaScript

If you are new to JavaScript, this message can look like the browser is speaking a different language. It is not. It is telling you something simple: your…

Published 2026-09-06Updated 2026-09-128 min read
Close-up of a crested gecko's eye showcasing detailed textures and patterns.
Close-up of a crested gecko's eye showcasing detailed textures and patterns. Photo by Andrej Zeman on Pexels.

You open the browser console and see this:

Uncaught TypeError: Cannot read properties of null (reading 'textContent')

If you are new to JavaScript, this message can look like the browser is speaking a different language. It is not. It is telling you something simple: your code asked for an element that does not exist, then tried to read a property from that empty result.

This is one of the most common errors beginners hit when they start working with web pages. The good news? The fix is usually straightforward once you know what to look for.

What This Error Is Telling You

When you select an element from your page, you expect to get that element back. But when no match is found, JavaScript does not throw a friendly "element not found" warning. Instead, it gives you a value called null.

Think of null as JavaScript's way of saying "nothing was found here." It is an empty shelf where you expected a book.

Now imagine trying to open that missing book to read a page. You cannot, because there is no book. That is exactly what your code is doing:

document.querySelector("#title").textContent = "Hello";

If no element with the id title exists, document.querySelector("#title") returns null. Then your code tries to read .textContent from that empty result—and JavaScript stops and reports the error.

The error is a TypeError, which means you tried to perform an operation on a value that does not support it. In this case, you tried to read a property from null, and null has no properties to give you.

This error commonly appears when you use querySelector or getElementById, because both return null when they cannot find a matching element. The debugging path is the same for either method.

Knowledge check

Check your understanding

Answer this question before you continue.

What does `document.querySelector("#title")` return when no element with the id `title` exists?
Single Choice

Focus: Explain what null means when a DOM selector finds no matching element.

A Tiny Example That Triggers the Error

Let us make this concrete. Create a simple HTML file and open it in your browser:

<!DOCTYPE html>
<html>
<head>
  <title>Null Error Example</title>
</head>
<body>
  <h1>My Page</h1>

  <script>
    const heading = document.querySelector("#subtitle");
    heading.textContent = "Updated heading";
  </script>
</body>
</html>

Open this file in your browser and look at the console. You will see:

Uncaught TypeError: Cannot read properties of null (reading 'textContent')

Why? The page has an <h1> with the text "My Page," but there is no element with the id subtitle. The selector #subtitle looks for an element with that id, finds nothing, and returns null.

The fix is to make the selector match something that actually exists:

<!DOCTYPE html>
<html>
<head>
  <title>Null Error Example</title>
</head>
<body>
  <h1 id="subtitle">My Page</h1>

  <script>
    const heading = document.querySelector("#subtitle");
    heading.textContent = "Updated heading";
  </script>
</body>
</html>

Now the page displays "Updated heading" instead of "My Page," and the console is clean.

Knowledge check

Check your understanding

Answer this question before you continue.

What will the page display after this corrected code runs?
Output Prediction

Focus: Predict the result of correcting a selector so it matches an existing element.

<h1 id="subtitle">My Page</h1>
<script>
  const heading = document.querySelector("#subtitle");
  heading.textContent = "Updated heading";
</script>

Debug in This Order

A flowchart begins with a JavaScript null-property error, then directs the learner to inspect the expression before the property and log its result. If the result is null, the learner compares the selector with the HTML; if the selector matches, the learner checks whether the script ran before the element existed and either moves the script or waits for the DOM.
Follow this path to determine whether null came from a selector mismatch or code that ran too early.

When you see this error, do not guess. Run through these steps in order:

  1. Find the expression before the property. The error names the property, like textContent. Look left of that dot to see which element lookup returned null.
  2. Log the result. Add console.log right before the failing line to confirm the value is null.
  3. Compare the selector with your HTML. Check spelling, case, and whether the element actually exists on the page.
  4. Check script timing. If the selector matches perfectly, ask whether the script ran before the element was created.

The rest of this article walks through steps 3 and 4, because those are the two causes behind nearly every null-property error.

Cause 1: The Selector Does Not Match

The most common cause of this error is a mismatch between the selector string and the actual HTML. This can happen in several ways:

  • A misspelled id: your HTML has id="header" but your selector is #hader.
  • Wrong case: your HTML has id="Title" but your selector is #title. Ids are case-sensitive.
  • Wrong element type: you used a class selector like .button when the element has an id, not a class.
  • The element simply does not exist on the page.

Here is a broken example:

const message = document.querySelector(".warning-message");
message.innerHTML = "Something went wrong";

If no element has the class warning-message, this code crashes. The quickest way to confirm the problem is to log the result before touching it:

const message = document.querySelector(".warning-message");
console.log(message); // null means no element was found

When you see null in the console, you know the lookup found nothing at that moment. Compare the selector string with your HTML carefully. Check the spelling, check the case, and confirm the element is actually on the page.

The same rule applies if you used getElementById instead:

const message = document.getElementById("warning-message");
console.log(message); // null means no element was found

The debugging step is identical: verify that the id in your JavaScript matches the id in your HTML.

Knowledge check

Check your understanding

Answer this question before you continue.

Which change fixes the null error caused by the selector not matching the HTML id?
Debugging

Focus: Repair a selector whose capitalization does not match the HTML id.

<p id="intro">Welcome</p>
<script>
  const paragraph = document.querySelector("#Intro");
  paragraph.textContent = "Hello there";
</script>

Cause 2: The Script Runs Before the Element Exists

The second common cause is timing. The browser builds your page from top to bottom. When it reaches a <script> tag, it stops and runs that JavaScript immediately. If your script sits in the <head> and tries to select an element in the <body>, that element has not been created yet.

<!DOCTYPE html>
<html>
<head>
  <title>Timing Problem</title>
  <script>
    const button = document.querySelector("#submit-btn");
    button.textContent = "Send"; // Error: button is null
  </script>
</head>
<body>
  <button id="submit-btn">Submit</button>
</body>
</html>

When the script runs, the browser has not reached the <button> yet. The element does not exist at that moment, so querySelector returns null. Notice that the selector is correct—the problem is when the code runs.

There are two beginner-safe fixes.

Fix 1: Move the script to the end of the body.

<!DOCTYPE html>
<html>
<head>
  <title>Timing Problem</title>
</head>
<body>
  <button id="submit-btn">Submit</button>

  <script>
    const button = document.querySelector("#submit-btn");
    button.textContent = "Send";
  </script>
</body>
</html>

By the time the browser reaches the script, the button already exists. This is the simplest fix and works well for most pages.

Fix 2: Wait for the DOM to be ready.

You can also tell your code to wait until the browser has finished building the page structure:

<!DOCTYPE html>
<html>
<head>
  <title>Timing Problem</title>
  <script>
    document.addEventListener("DOMContentLoaded", function () {
      const button = document.querySelector("#submit-btn");
      button.textContent = "Send";
    });
  </script>
</head>
<body>
  <button id="submit-btn">Submit</button>
</body>
</html>

The DOMContentLoaded event fires when the browser has parsed the full HTML. Your code inside the listener runs only after the button exists.

Both fixes work. Moving the script to the end of the body is easier to understand at this stage. The DOMContentLoaded approach becomes more useful when you have reasons to keep scripts in the <head>.

Knowledge check

Check your understanding

Answer this question before you continue.

The selector is correct, but the script is in the head before the button is parsed. Which change fixes the timing problem?
Debugging

Focus: Choose a beginner-safe repair when a correct selector runs before its element exists.

<head>
  <script>
    const button = document.querySelector("#submit-btn");
    button.textContent = "Send";
  </script>
</head>
<body>
  <button id="submit-btn">Submit</button>
</body>

A Common Beginner Mistake to Avoid

When beginners see this error, a tempting reaction is to guess. Maybe the property name is wrong? Maybe it should be innerHTML instead of textContent?

That instinct points at the wrong suspect. The error is not about the property. It is about the element. If the element is null, every property you try to read will fail, no matter which one you choose.

A better habit is to check that the element exists before you touch it:

const heading = document.querySelector("#subtitle");

if (heading) {
  heading.textContent = "Updated heading";
} else {
  console.log("Element not found");
}

The if (heading) check passes only when heading is not null. This guard stops the crash and tells you what went wrong. But be clear about what it does not do: it does not repair a broken selector or fix a timing problem. If the heading is required on your page, you still need to debug why the lookup returned null.

Use this guard when an element is genuinely optional—for example, a decorative banner that may or may not exist. When the element must be there, treat the guard as a diagnostic signal, not the final fix.

Your Turn: Fix It Yourself

Here is a small broken snippet. Try to fix it on your own:

<!DOCTYPE html>
<html>
<head>
  <title>Practice Fix</title>
</head>
<body>
  <p id="intro">Welcome</p>

  <script>
    const paragraph = document.querySelector("#Intro");
    paragraph.textContent = "Hello there";
  </script>
</body>
</html>

When you run this, you will see the null error in the console. Your goal: make the page display "Hello there" with no errors.

Hint: Look at the id in the HTML, then look at the selector string. Are they identical?

When you find the fix, try breaking it again on purpose. Change the id, move the script into the <head>, and watch the error return. The fastest way to make this lesson stick is to cause the error yourself, fix it, and then cause it again.

Once you are comfortable fixing this error, a good next step is learning how to change element content and respond to user clicks. Those skills build directly on selecting elements correctly—and you will see this null error far less often when you know exactly what your selectors are returning.

Knowledge check

Final check

Finish the article by checking the ideas you just learned.

A selector returned `null`, and reading `textContent` caused an error. Which statement best identifies the real problem?
Question 1 of 2Misconception Check

Focus: Distinguish a null element lookup problem from a property-name problem.

What is the accurate description of this guard? `if (heading) { heading.textContent = "Updated heading"; }`
Question 2 of 2Misconception Check

Focus: Explain what an existence guard does and does not repair.

References

  1. TypeError: null/undefined hat keine Eigenschaften - JavaScript | MDNdeveloper.mozilla.org
7sources checked
7source domains
5searches run

Research updated Sep 6, 2026

Keep learning

Related tutorials

Continue with nearby JavaScript topics and beginner-friendly explanations.

From above of surface of wavy blue sea on sunny day as background
beginner
8 min read

Changing DOM Content

A static page is a finished product. A dynamic page is a conversation: the user clicks, submits, or types, and the page answers. That answer usually means…

Read tutorial
A stunning view of a bright blue sky filled with fluffy clouds, capturing a serene and peaceful atmosphere.
beginner
8 min read

Creating and Removing Elements

A static HTML page is frozen the moment it loads. Real sites keep changing after that—a to-do item appears, a cart entry disappears, a new message slides…

Read tutorial