swc-project/swc · error · TypeError
Invalid attempt to spread non-iterable instance. In order to
Error message
Invalid attempt to spread non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator]() method.
What it means
Array/call spread (`[...x]`, `f(...x)`) is lowered to `_to_consumable_array`, which accepts iterables and array-likes. When the spread operand is neither, the chain falls through to `_non_iterable_spread()`, throwing this TypeError — identical to what a native engine does when spreading a non-iterable.
Source
Thrown at crates/swc_ecma_transforms_base/src/helpers/generated/_non_iterable_spread.rs:11
// This file is generated by `cargo codegen helpers`. DO NOT MODIFY.
use super::{HelperDef, HelperName};
pub const DEF: HelperDef = HelperDef {
name: HelperName::non_iterable_spread,
local: "_non_iterable_spread",
import_path: "@swc/helpers/_/_non_iterable_spread",
#[cfg(feature = "inline-helpers")]
source: r#"function _non_iterable_spread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
"#,
#[cfg(feature = "inline-helpers")]
deps: super::HelperBitmap::from_bits(0x00000000000000080000000000000000),
};
#[cfg(feature = "inline-helpers")]
pub fn stmts() -> &'static [swc_ecma_ast::Stmt] {
static STMTS: once_cell::sync::Lazy<Vec<swc_ecma_ast::Stmt>> =
once_cell::sync::Lazy::new(|| super::super::parse(DEF.source, DEF.import_path));
&STMTS
}
View on GitHub (pinned to 5176682b65)
Solutions
- For plain objects use `Object.keys/values/entries(obj)` instead of spread.
- Guard nullable sources: `Array.from(x ?? [])`.
- Convert array-likes explicitly with `Array.from(x)` before spreading.
- Fix the producer so it returns an iterable where a spread is expected.
Example fix
// before
const args = [...options]; // options = { verbose: true }
// TypeError: Invalid attempt to spread non-iterable instance.
// after
const args = Object.values(options ?? {}); Defensive patterns
Strategy: type-guard
Validate before calling
// Check spread operands before `[...x]` or `f(...x)`. const isSpreadable = (v) => v != null && (typeof v[Symbol.iterator] === 'function' || typeof v.length === 'number'); const merged = isSpreadable(extra) ? [...base, ...extra] : [...base];
Type guard
const isSpreadable = <T>(v: unknown): v is Iterable<T> | ArrayLike<T> =>
v != null &&
(typeof (v as Iterable<T>)[Symbol.iterator] === 'function' ||
typeof (v as ArrayLike<T>).length === 'number'); Try / catch
try {
args = [...source];
} catch (err) {
if (err instanceof TypeError && /non-iterable/.test(err.message)) {
args = Object.values(source ?? {}); // graceful fallback for plain objects
} else throw err;
} Prevention
- Prefer `Array.from(x ?? [])` at boundaries where the shape is uncertain.
- Use `Object.values/entries` for plain objects — spread is for iterables only.
- Add unit tests for the empty/null/undefined paths of every spread expression consuming external data.
When it happens
Trigger: `[...obj]` or `fn(...obj)` where `obj` is a plain object, number, boolean, `null`, or `undefined` — anything without `[Symbol.iterator]` and without a numeric `length`.
Common situations: Spreading a plain object expecting its values (should be `Object.values`); spreading the result of an optional chain that is `undefined` (`[...(map && map.values())]` patterns); spreading older array-like DOM objects in transpiled output.
Related errors
- Invalid attempt to destructure non-iterable instance. In ord
- Cannot destructure ${o}
- Object is not iterable.
- failed to set property
- using declarations can only be used with objects, functions,
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/82abd9c0cc5f6f05.
Report an issue: GitHub.