{"record":{"id":"c83676b691027172","repo":"swc-project/swc","slug":"cannot-destructure-o","errorCode":null,"errorMessage":"Cannot destructure ${o}","messagePattern":"Cannot destructure (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_base/src/helpers/generated/_object_destructuring_empty.rs","lineNumber":11,"sourceCode":"// This file is generated by `cargo codegen helpers`. DO NOT MODIFY.\n\nuse super::{HelperDef, HelperName};\n\npub const DEF: HelperDef = HelperDef {\n    name: HelperName::object_destructuring_empty,\n    local: \"_object_destructuring_empty\",\n    import_path: \"@swc/helpers/_/_object_destructuring_empty\",\n    #[cfg(feature = \"inline-helpers\")]\n    source: r#\"function _object_destructuring_empty(o) {\n    if (o === null || o === void 0) throw new TypeError(\"Cannot destructure \" + o);\n\n    return o;\n}\n\"#,\n    #[cfg(feature = \"inline-helpers\")]\n    deps: super::HelperBitmap::from_bits(0x00000000000000100000000000000000),\n};\n\n#[cfg(feature = \"inline-helpers\")]\npub fn stmts() -> &'static [swc_ecma_ast::Stmt] {\n    static STMTS: once_cell::sync::Lazy<Vec<swc_ecma_ast::Stmt>> =\n        once_cell::sync::Lazy::new(|| super::super::parse(DEF.source, DEF.import_path));\n    &STMTS\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_base/src/helpers/generated/_object_destructuring_empty.rs#L1-L26","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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."],"exampleFix":"// before\nfunction render({ theme }) {}\n// called with no argument -> TypeError: Cannot destructure undefined\n// after\nfunction render({ theme } = {}) {}","handlingStrategy":"validation","validationCode":"// Null-check before object destructuring, or default the pattern at the boundary.\nfunction render(options) {\n  if (options == null) options = {};\n  const { theme, layout } = options; // safe now\n}\n// or: const { theme, layout } = options ?? {};","typeGuard":"const isNonNullObject = (v: unknown): v is Record<string, unknown> =>\n  typeof v === 'object' && v !== null;","tryCatchPattern":"try {\n  const { a } = resp;\n} catch (err) {\n  if (err instanceof TypeError && /^Cannot destructure/.test(err.message)) {\n    // resp was null/undefined — retry with a default shape\n    const { a = null } = {};\n  } else throw err;\n}","preventionTips":["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."],"tags":["destructuring","null","undefined","es2015","typeerror"],"backgroundTag":"destructuring-null-undefined","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}