Skip to main content

How to Resolve "TypeError: querySelectorAll is not a function" Error in JavaScript

The TypeError: ... .querySelectorAll is not a function is a common error in client-side JavaScript. It occurs when you try to call the .querySelectorAll() method on a value that is not a valid object for this method, such as a NodeList (a collection of elements), null, or a plain string.

This guide will explain the fundamental reason this error happens, walk you through the most common scenarios where it occurs, and show you how to write "defensive" code to prevent it.

The Core Problem: Where querySelectorAll Can Be Called

The .querySelectorAll() method is a function that exists on two specific types of objects in the DOM:

  1. The global document object (to search the entire page).
  2. Individual Element objects (to search within the descendants of that specific element).

The error is the JavaScript engine telling you, "The thing you're trying to search inside doesn't have a querySelectorAll function because it's not a document or a single Element."

Cause 1 (Most Common): Calling it on a NodeList (a Collection of Elements)

This is the most frequent cause of the error. You use document.querySelectorAll() to get a list of elements, and then you incorrectly try to call querySelectorAll() again on that entire list.

Example of problem: HTML:

<div class="container">
<p class="item">Item 1</p>
</div>
<div class="container">
<p class="item">Item 2</p>
</div>

JavaScript:

// Problem: `querySelectorAll` returns a NodeList of ALL matching elements.
let containers = document.querySelectorAll('.container');

// This will throw the error because `containers` is a list, not a single element.
// You can't ask a list of containers to find an item.
let items = containers.querySelectorAll('.item');

Error Output:

Uncaught TypeError: containers.querySelectorAll is not a function

Solution: you must either iterate over the collection and query each element individually, or (more commonly) refine your initial selector to be more specific.

Solution A: Iterate over the NodeList If you need to perform a search inside each element of the collection, use a forEach() loop.

let containers = document.querySelectorAll('.container');

containers.forEach(container => {
// Correct: Call the method on each individual element inside the loop.
let item = container.querySelector('.item'); // Using querySelector for the first match
if (item) {
console.log(item.textContent);
}
});

Solution B (Often Better): Refine the Initial Selector If your goal is just to find all .item elements that are inside a .container, you can do that with a single, more specific CSS selector.

// Correct: This selector finds all elements with class 'item'
// that are descendants of an element with class 'container'.
let items = document.querySelectorAll('.container .item');

items.forEach(item => {
console.log(item.textContent);
});

Cause 2: Calling it on null

This happens when your initial element selector fails to find any matching element, so it returns null. Trying to call any method on null will always result in a TypeError.

Example of problem: HTML:

<!-- There is no element with the ID "my-element" -->

JavaScript:

// Problem: `querySelector` will return `null` because the ID doesn't exist.
let myElement = document.querySelector('#my-element');

// This will throw "TypeError: Cannot read properties of null (reading 'querySelectorAll')"
let children = myElement.querySelectorAll('p');

Solution: always add a "guard clause" to check if your element was actually found before you try to use it.

let myElement = document.querySelector('#my-element');

// Correct: Check if the element exists before using it.
if (myElement) {
let children = myElement.querySelectorAll('p');
console.log(children);
} else {
console.error('Error: Could not find the element with ID "my-element".');
}
note

You can also use optional chaining (?.) for a more concise check if you simply want to do nothing when the element is missing:

let children = document.querySelector('#my-element')?.querySelectorAll('p');
// `children` will be `undefined` if the element doesn't exist, and no error is thrown.

A Note on Misspellings

A simple typo can also cause this error. The method is camelCased: querySelectorAll.

  • queryselectorall (all lowercase) will fail.
  • QuerySelectorAll (incorrect capitalization) will fail.

Ensure your method name is spelled and cased correctly.

Conclusion

The TypeError: querySelectorAll is not a function is always a sign that you are not calling the method on a valid document or Element object.

To solve it, follow this diagnostic checklist:

  1. Inspect your variable: Use console.log() to see what the variable you are calling the method on actually is. Is it a NodeList? null?
  2. If it's a NodeList, you need to either loop through it or refine your initial selector to be more specific.
  3. If it could be null, add a guard clause (if (element) { ... }) to handle cases where the element might not be found.
  4. Check your spelling: Ensure the method is spelled correctly: querySelectorAll.