{"record":{"id":"a489091f2c6f87ee","repo":"swc-project/swc","slug":"illegal-conversion-cannot-convert-to-patoutp","errorCode":null,"errorMessage":"illegal conversion: Cannot convert {:?} to PatOutput","messagePattern":"illegal conversion: Cannot convert (.+?) to PatOutput","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_estree_compat/src/babelify/pat.rs","lineNumber":36,"sourceCode":"    Array(ArrayPattern),\n    Rest(RestElement),\n    Object(ObjectPattern),\n    Assign(AssignmentPattern),\n    Expr(Box<Expression>),\n}\n\nimpl Babelify for Pat {\n    type Output = PatOutput;\n\n    fn babelify(self, ctx: &Context) -> Self::Output {\n        match self {\n            Pat::Ident(i) => PatOutput::Id(i.babelify(ctx)),\n            Pat::Array(a) => PatOutput::Array(a.babelify(ctx)),\n            Pat::Rest(r) => PatOutput::Rest(r.babelify(ctx)),\n            Pat::Object(o) => PatOutput::Object(o.babelify(ctx)),\n            Pat::Assign(a) => PatOutput::Assign(a.babelify(ctx)),\n            Pat::Expr(e) => PatOutput::Expr(Box::alloc().init(e.babelify(ctx).into())),\n            Pat::Invalid(_) => panic!(\n                \"illegal conversion: Cannot convert {:?} to PatOutput\",\n                &self\n            ),\n            #[cfg(swc_ast_unknown)]\n            _ => panic!(\"unable to access unknown nodes\"),\n        }\n    }\n}\n\nimpl From<PatOutput> for Pattern {\n    fn from(pat: PatOutput) -> Self {\n        match pat {\n            PatOutput::Assign(a) => Pattern::Assignment(a),\n            PatOutput::Array(a) => Pattern::Array(a),\n            PatOutput::Object(o) => Pattern::Object(o),\n            _ => panic!(\"illegal conversion: Cannot convert {:?} to Pattern\", &pat),\n        }\n    }","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_estree_compat/src/babelify/pat.rs#L18-L54","documentation":"When swc_ecma_parser runs with error recovery, malformed binding patterns are replaced by `Pat::Invalid` placeholder nodes instead of aborting the parse. ESTree has no representation for an invalid pattern, so babelify panics rather than inventing data. Hitting this panic means the program you are converting still contains parser-recovery artifacts.","triggerScenarios":"Parse source with recovery enabled, ignore the error list, then babelify: inputs like `var {a b} = x;`, `function f([a,,,) {}` or `let [1] = y;` leave Pat::Invalid nodes that reach pat.rs:36 during conversion.","commonSituations":"Lint/autofix/codemod tools that deliberately parse broken code with a lenient parser config and then convert the recovered AST to estree; pipelines that never call `parser.take_errors()`; hand-built ASTs using `Pat::Invalid` (e.g. via `Take::dummy()`).","solutions":["After parsing, abort when `parser.take_errors()` is non-empty before calling babelify","Fix the malformed destructuring/binding syntax in the input source","Re-parse without recovery so invalid input fails at the parse stage with a real diagnostic","Maintainer: return an error or map to an estree Invalid node instead of panicking on Pat::Invalid"],"exampleFix":"// before\nlet module = parser.parse_module().map_err(|e| anyhow!(e))?;\nlet estree = module.babelify(); // panics if recovery left Pat::Invalid\n\n// after\nlet module = parser.parse_module().map_err(|e| anyhow!(e))?;\nif !parser.take_errors().is_empty() {\n    return Err(anyhow!(\"refusing to babelify recovered AST\"));\n}\nlet estree = module.babelify();","handlingStrategy":"validation","validationCode":"use swc_ecma_ast::{Module, Pat};\nuse swc_ecma_visit::{Visit, VisitWith};\n\n#[derive(Default)]\nstruct InvalidPats(Vec<swc_common::Span>);\n\nimpl Visit for InvalidPats {\n    fn visit_pat(&mut self, p: &Pat) {\n        if let Pat::Invalid(i) = p { self.0.push(i.span); }\n        p.visit_children_with(self);\n    }\n}\n\nfn has_invalid_pats(m: &Module) -> bool {\n    let mut v = InvalidPats::default();\n    m.visit_with(&mut v);\n    !v.0.is_empty()\n}","typeGuard":"fn is_convertible_pat(p: &Pat) -> bool {\n    !matches!(p, Pat::Invalid(_))\n}","tryCatchPattern":"use std::panic::{catch_unwind, AssertUnwindSafe};\n\nlet estree = catch_unwind(AssertUnwindSafe(|| program.babelify()))\n    .map_err(|_| anyhow!(\"AST contains invalid/recovered nodes\"))?;","preventionTips":["Always check `parser.take_errors()` after parsing and abort before estree conversion when non-empty","Do not use Pat::Invalid / Take::dummy() as placeholder in ASTs destined for babelify","Add fixture tests containing broken destructuring to verify your pipeline rejects them","Prefer failing the whole conversion over partial output from recovered ASTs"],"tags":["rust","swc","babelify","destructuring","parser-error-recovery","invalid-node","panic"],"backgroundTag":"unsupported-ast-conversion","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}