Last updated: Mar 3, 2024
Reading time·4 min

The "Cannot read properties of null (reading 'querySelector')" error occurs for 2 reasons:
querySelector() method on a null value (DOM element that
doesn't exist).
Here is an example of how the error occurs.
const element = null; // ⛔️ Uncaught TypeError: Cannot read properties of null (reading 'querySelector') const box = element.querySelector('#box');
Here is another example.
const el = undefined; // ⛔️ Uncaught TypeError: Cannot read properties of undefined (reading 'querySelector') const box = el.querySelector('#box');
querySelectorMake sure you're using the correct id when selecting the DOM element.
The error often occurs after providing an invalid id to the getElementById()
method.
const element = document.getElementById('does-not-exist'); console.log(element); // 👉️ null // ⛔️ Cannot read properties of null (reading 'querySelector') const box = element.querySelector('#box');
id to the getElementById method, so we got anull value back. Calling the querySelector() method on a null value causes the error.If you got the error "Cannot read properties of undefined (reading
'querySelector')", you probably used the getElementsByClassName() method.
const elements = document.getElementsByClassName('does-not-exist'); console.log(elements); // 👉️ [] // ⛔️ Cannot read properties of undefined (reading 'querySelector') const box = elements[0].querySelector('#box');
We passed a non-existent class name to the getElementsByClassName() method, so
we got an empty array-like object back.
Trying to access an array at an index out of bounds, returns an undefined
value and calling the querySelector() method on an undefined value causes
the error.
Place the JS script tag at the bottom of the body tag.
The JS script should run after the DOM elements are created.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <!-- ⛔️ BAD - script is run before div exists ⛔️ --> <script src="index.js"></script> <div id="container"> <div id="box">Text</div> </div> </body> </html>
The JS script tag is placed above the DOM elements it tries to access, so the
div element won't be accessible inside the index.js file.
const element = document.getElementById('container'); console.log(element); // 👉️ null // ⛔️ Cannot read properties of null (reading 'querySelector') const box = element.querySelector('#box');
Instead, place the JS script tag at the bottom of the body, after the DOM elements it tries to access.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <div id="container"> <div id="box">Text</div> </div> <!-- ✅ GOOD - div already exists ✅ --> <script src="index.js"></script> </body> </html>

Now we can access the div element inside of the index.js file.
const element = document.getElementById('container'); console.log(element); // 👉️ div#container // ✅ Works const box = element.querySelector('#box'); console.log(box); // 👉️ div#box

HTML code is parsed from top to bottom, so the script tag has to come after the DOM elements it needs access to.
The "Cannot read properties of null (reading 'querySelectorAll')" error occurs for 2 reasons:
querySelectorAll() method on a null value (DOM element that
doesn't exist).
Here is an example of how the error occurs.
const el = null; // ⛔️ Uncaught TypeError: Cannot read properties of null (reading 'querySelectorAll') el.querySelectorAll('div.box');
Here is another example.
const el = undefined; // ⛔️ Uncaught TypeError: Cannot read properties of undefined (reading 'querySelectorAll') el.querySelectorAll('div.box');
Make sure the id you're using to get the element exists in the DOM.
The error often occurs after providing an invalid id to the getElementById()
method.
const el = document.getElementById('does-not-exist'); console.log(el); // 👉️ null // ⛔️ Cannot read properties of null (reading 'querySelectorAll') el.querySelectorAll('div.box');
We passed a non-existent id to the getElementById() method and got a null
value back. Calling the querySelectorAll() method on a null value causes the
error.
If you got the error "Cannot read properties of undefined (reading
'querySelectorAll')", you probably used the getElementsByClassName() method.
const elements = document.getElementsByClassName('does-not-exist'); console.log(elements); // 👉️ [] // ⛔️ Cannot read properties of undefined (reading 'querySelectorAll') const boxes = elements[0].querySelectorAll('div.box');
We passed a non-existent class name to the getElementsByClassName() method and
got an empty array-like object back.
Accessing an array at an index out of bounds returns undefined. Calling the
querySelectorAll() method on an undefined value throws the error.
Place the JS script tag at the bottom of the body tag.
The script should run after the DOM elements have been created.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <!-- ⛔️ BAD - script runs before div exists ⛔️ --> <script src="index.js"></script> <div id="container"> <div class="box">Box 1</div> <div class="box">Box 2</div> </div> </body> </html>
Notice that the JS script tag is placed above the code that declares the div
element. This means that the index.js file cannot access the div element.
const el = document.getElementById('container'); console.log(el); // 👉️ null // ⛔️ Cannot read properties of null (reading 'querySelectorAll') el.querySelectorAll('div.box');
Instead, you should move the JS script tag to the bottom of the body, after the elements it tries to access.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <div id="container"> <div class="box">Box 1</div> <div class="box">Box 2</div> </div> <!-- ✅ GOOD - div already exists ✅ --> <script src="index.js"></script> </body> </html>
Now our index.js file has access to the DOM elements.
const el = document.getElementById('container'); console.log(el); // 👉️ div#container // ✅ Works const boxes = el.querySelectorAll('div.box'); console.log(boxes); // 👉️ [div.box, div.box]
HTML code is parsed from top to bottom, so the script tag has to come after the DOM elements it needs access to.