Fix: TypeError X is not iterable
You tried to spread, loop, or destructure a plain object. Here's why it fails and three ways to fix it.
Last updated: October 2026
Convert the object to an array first. Use one of these three methods depending on what you need:
// Iterate over key-value pairs
for (const [key, value] of Object.entries(obj)) { ... }
// Iterate over keys only
for (const key of Object.keys(obj)) { ... }
// Iterate over values only
for (const value of Object.values(obj)) { ... }
What the error means
JavaScript has two kinds of collections: iterables (arrays, strings, Maps, Sets) and non-iterables (plain objects). Only iterables work with for-of, spread ([...x]), and array destructuring.
// Iterable — works
for (const x of [1, 2, 3]) { }
for (const x of "abc") { }
for (const x of new Set([1, 2])) { }
for (const [k, v] of new Map([[1, 2]])) { }
// Non-iterable — throws
for (const x of { a: 1, b: 2 }) { } // ❌ TypeError
Why it happens
Plain objects don't have a Symbol.iterator method. That's the mechanism for-of, spread, and array destructuring rely on. Arrays, strings, Maps, and Sets all implement it. Objects don't.
// Arrays have it
typeof [].constructor.prototype[Symbol.iterator]; // "function"
// Objects don't
typeof {}.constructor.prototype[Symbol.iterator]; // "undefined"
// That's the entire reason for this error
Note: The spread operator {...obj} (object spread) works fine on objects. The error only occurs with array spread [...obj] or iteration.
Three fixes depending on what you need
You need both keys and values
Object.entries() returns an array of [key, value] pairs. Destructure inside the loop.
const config = { theme: "dark", lang: "en" };
// Loop over entries
for (const [key, value] of Object.entries(config)) {
console.log(key, value);
// theme dark
// lang en
}
// Or map over entries
const html = Object.entries(config)
.map(([k, v]) => `<div>${k}: ${v}</div>`)
.join("");
You only need the keys
Object.keys() returns an array of the object's own enumerable property names.
const user = { name: "Alice", age: 30 };
for (const key of Object.keys(user)) {
console.log(key);
// name
// age
}
// Check required fields
const required = ["name", "email"];
const missing = required.filter(
key => !Object.keys(user).includes(key)
);
You only need the values
Object.values() returns an array of the object's own enumerable property values.
const scores = { alice: 85, bob: 92, cara: 78 };
// Sum all scores
const total = Object.values(scores)
.reduce((sum, score) => sum + score, 0);
// 255
// Highest scorer
const highest = Math.max(...Object.values(scores));
// 92
🛡️ How to prevent it
- Log before you iterate.
console.log(typeof value, value)reveals if it's an object or array. - Use TypeScript. The compiler won't allow
for-ofon non-iterable types. - Name objects differently from arrays.
userMapvsuserListmakes the shape obvious. - Return consistent types. Don't return an object on one path and an array on another.
- Remember
Object.entriesexists. It converts the shape for you — no need to force iteration on objects.
What works on objects vs arrays
| Operation | Object | Array |
|---|---|---|
for-of | ❌ | ✅ |
[...x] spread | ❌ | ✅ |
{...x} spread | ✅ | ⚠️ Spreads indices |
Array.isArray(x) | false | true |
x.length | undefined | number |
Object.entries(x) | ✅ | ✅ (index-value pairs) |
❓ Frequently asked questions
How do I fix TypeError X is not iterable in JavaScript?
The object you're trying to iterate (with spread, for-of, or destructuring) is a plain object, not an array or iterable. Convert it first: use Object.entries(obj) to iterate key-value pairs, Object.keys(obj) for keys, or Object.values(obj) for values.
Why can't I spread a plain object with for-of?
for-of requires an object with a Symbol.iterator method. Plain objects don't have one by default. Arrays, strings, Maps, Sets, and TypedArrays do. To iterate an object, use Object.entries, Object.keys, or Object.values.
What is the difference between spreading objects and spreading arrays?
Spreading an array ([...arr]) creates a new array with the same elements. Spreading an object ({...obj}) creates a shallow copy with the same properties. The error only occurs when you spread an object into an array context or iterate it with for-of.
How do I convert an object to an array?
Use Object.entries(obj) to get an array of [key, value] pairs, Object.keys(obj) for keys, or Object.values(obj) for values. Each returns a real array you can iterate with any array method.
Why does this error only happen sometimes?
The error depends on what value is assigned at runtime. If the variable holds an array on one code path and an object on another, only the object path throws. Log the value before iterating to confirm its actual type.