swc-project/swc · error · TypeError
Cannot destructure ${o}
Error message
Cannot destructure ${o} What it means
When SWC's ES2015 destructuring transform lowers object patterns, it inserts `_object_destructuring_empty(o)` to reproduce the native check: destructuring an object pattern from `null` or `undefined` must throw. The helper throws `Cannot destructure <value>` (e.g. `Cannot destructure null`) exactly where native engines would.
Source
Thrown at crates/swc_ecma_transforms_base/src/helpers/generated/_object_destructuring_empty.rs:11
// This file is generated by `cargo codegen helpers`. DO NOT MODIFY.
use super::{HelperDef, HelperName};
pub const DEF: HelperDef = HelperDef {
name: HelperName::object_destructuring_empty,
local: "_object_destructuring_empty",
import_path: "@swc/helpers/_/_object_destructuring_empty",
#[cfg(feature = "inline-helpers")]
source: r#"function _object_destructuring_empty(o) {
if (o === null || o === void 0) throw new TypeError("Cannot destructure " + o);
return o;
}
"#,
#[cfg(feature = "inline-helpers")]
deps: super::HelperBitmap::from_bits(0x00000000000000100000000000000000),
};
#[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
- Give the parameter a default: `function f({ a } = {}) { ... }`.
- Coalesce at the boundary: `const { a } = resp ?? {};` or `const { a } = resp || {};`.
- Add an early guard: `if (!resp) return;` before destructuring.
- Fix the caller to always pass an object.
Example fix
// before
function render({ theme }) {}
// called with no argument -> TypeError: Cannot destructure undefined
// after
function render({ theme } = {}) {} Defensive patterns
Strategy: validation
Validate before calling
// Null-check before object destructuring, or default the pattern at the boundary.
function render(options) {
if (options == null) options = {};
const { theme, layout } = options; // safe now
}
// or: const { theme, layout } = options ?? {}; Type guard
const isNonNullObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null;
Try / catch
try {
const { a } = resp;
} catch (err) {
if (err instanceof TypeError && /^Cannot destructure/.test(err.message)) {
// resp was null/undefined — retry with a default shape
const { a = null } = {};
} else throw err;
} Prevention
- Always give destructured parameters a default: `function f(opts = {}) { const { a } = opts; }`.
- Validate parsed JSON against a schema before destructuring nested fields.
- Enable strict TS settings (`strictNullChecks`) so nullable destructuring sources are flagged.
When it happens
Trigger: `const { a } = v` (including empty pattern `const {} = v` and defaulted nested patterns) where `v` is `null` or `undefined`; also `function f({ a }) {}` invoked as `f()` — the undefined argument is destructured.
Common situations: A config object parameter not passed by a caller; `JSON.parse` returning `null`; an API field becoming nullable; refactoring positional arguments into an options object while some call sites were missed.
Related errors
- Invalid attempt to destructure non-iterable instance. In ord
- Invalid attempt to spread non-iterable instance. In order to
- rest pattern should handled by array pattern handler: {:?}
- failed to set property
- Object is not iterable.
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/c83676b691027172.
Report an issue: GitHub.