How to Resolve "TypeError: Cannot read properties of null (reading 'querySelector')" Error in JavaScript
The JavaScript error TypeError: Cannot read properties of null (reading 'querySelector') is one of the most common errors encountered by developers working with the DOM. It is almost always caused by a timing issue: your JavaScript code is trying to find an HTML element before that element has been created in the DOM. A similar error, ...reading 'querySelectorAll', has the exact same cause and solution.
This guide will explain the two primary reasons this error occurs and provide the simple, standard solutions to fix it, ensuring your script can always find the elements it needs.
Understanding the Error: What null Means
Let's break down what the error message Cannot read properties of null (reading 'querySelector') is telling you.
- It tried to read the property
querySelector. - It tried to read it from a value that was
null.
This means you have a line of code that looks like this: someVariable.querySelector(...)
And at the moment that line was executed, the value of someVariable was null.
Example of code with error:
const myElement = null;
// This is the line that throws the error, because myElement is null
// ⛔️ Uncaught TypeError: Cannot read properties of null (reading 'querySelector')
const child = myElement.querySelector('#box');
This error is your browser's way of telling you, "You asked me to search for something inside an element, but that element doesn't exist."
Cause 1: The DOM Element Does Not Exist
The most straightforward cause is a simple typo or an incorrect selector. If you try to select an element that isn't in your HTML, the selection method will return null.
Example of code with error: HTML:
<div id="container">
<div id="box">My Box</div>
</div>
JavaScript:
// The ID 'container-main' does not exist in the HTML.
const container = document.getElementById('container-main');
// The value of 'container' is now null.
console.log(container);
// Output: null
// ⛔️ Uncaught TypeError: Cannot read properties of null (reading 'querySelector')
const box = container.querySelector('#box');
Because container is null, trying to call .querySelector() on it immediately throws the error. The same thing happens with querySelectorAll.
Cause 2: The Script is Executed Too Early
This is the most common cause of the error. The browser parses and executes your HTML file from top to bottom. If your <script> tag is placed in the <head> or at the top of the <body>, your JavaScript code will run before the browser has had a chance to create the HTML elements in the DOM.
Example of code with error: HTML:
<!DOCTYPE html>
<html>
<head>
<!-- ⛔️ BAD: The script runs before the div exists -->
<script src="index.js"></script>
</head>
<body>
<div id="container">
<div id="box">My Box</div>
</div>
</body>
</html>
JavaScript (index.js):
const container = document.getElementById('container');
// At this point, the <body> has not been parsed yet, so 'container' is not in the DOM.
console.log(container);
// Output: null
// ⛔️ Uncaught TypeError: Cannot read properties of null (reading 'querySelector')
const box = container.querySelector('#box');
Even though the HTML is correct, the timing is wrong, leading to the same null reference error.
Solution 1: Place Your <script> Tag at the End of the <body>
The simplest and most common solution is to move your <script> tag to be the very last thing before the closing </body> tag.
The Correct HTML Structure:
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
</head>
<body>
<!-- All of your HTML elements come first -->
<div id="container">
<div id="box">My Box</div>
</div>
<!-- ✅ GOOD: The script runs after all the elements above have been created -->
<script src="index.js"></script>
</body>
</html>
By the time the browser reaches this script, all the HTML elements above it are guaranteed to exist in the DOM, and your document.getElementById('container') call will successfully find the element.
Solution 2: Use a DOMContentLoaded Event Listener
A more robust and modern solution is to keep your <script> in the <head> but wrap your code in an event listener. The DOMContentLoaded event fires after all the HTML has been loaded and the DOM is ready, but before images and stylesheets are fully loaded.
This is the recommended best practice for professional development.
The Correct JavaScript:
// This script can be safely placed in the <head>
document.addEventListener('DOMContentLoaded', () => {
// All of your DOM manipulation code goes inside this function.
const container = document.getElementById('container');
// This code will not run until the DOM is ready, so 'container' will be found.
console.log(container);
// Output: <div id="container">...</div>
// ✅ Works perfectly
const box = container.querySelector('#box');
console.log(box);
// Output: <div id="box">...</div>
});
This pattern ensures your code never runs too early, regardless of where your <script> tag is placed.
Conclusion
The Cannot read properties of null error is a fundamental lesson in how the browser loads and executes code.
To fix it, always ensure your script only runs after the DOM is ready:
- Check your selectors: Make sure there are no typos in your
getElementByIdor other selector methods. - Move your
<script>tag: The simplest fix is to place your<script>tags at the very bottom of the<body>. - Use an event listener (Best Practice): The most robust solution is to wrap your code in a
DOMContentLoadedevent listener to guarantee the DOM is fully loaded before your script tries to access it.