swc-project/swc · error
illegal conversion: Cannot convert {:?} to LVal
Error message
illegal conversion: Cannot convert {:?} to LVal What it means
Babel's LVal accepts identifiers, destructuring patterns, rest elements and member expressions as assignment targets. When converting `PatOutput::Expr`, this From impl maps only `Expression::Member`; any other expression (binary, call, literal, ...) is not a legal assignment target in ESTree, so the conversion panics with 'illegal conversion: Cannot convert ... to LVal'.
Source
Thrown at crates/swc_estree_compat/src/babelify/pat.rs:80
PatOutput::Array(p) => ObjectPropVal::Pattern(PatternLike::ArrayPat(p)),
PatOutput::Rest(p) => ObjectPropVal::Pattern(PatternLike::RestEl(p)),
PatOutput::Object(p) => ObjectPropVal::Pattern(PatternLike::ObjectPat(p)),
PatOutput::Assign(p) => ObjectPropVal::Pattern(PatternLike::AssignmentPat(p)),
}
}
}
impl From<PatOutput> for LVal {
fn from(pat: PatOutput) -> Self {
match pat {
PatOutput::Id(i) => LVal::Id(i),
PatOutput::Array(a) => LVal::ArrayPat(a),
PatOutput::Rest(r) => LVal::RestEl(r),
PatOutput::Object(o) => LVal::ObjectPat(o),
PatOutput::Assign(a) => LVal::AssignmentPat(a),
PatOutput::Expr(expr) => match *expr {
Expression::Member(e) => LVal::MemberExpr(e),
_ => panic!("illegal conversion: Cannot convert {:?} to LVal", &expr),
},
}
}
}
impl From<PatOutput> for PatternLike {
fn from(pat: PatOutput) -> Self {
match pat {
PatOutput::Id(i) => PatternLike::Id(i),
PatOutput::Array(a) => PatternLike::ArrayPat(a),
PatOutput::Rest(r) => PatternLike::RestEl(r),
PatOutput::Object(o) => PatternLike::ObjectPat(o),
PatOutput::Assign(a) => PatternLike::AssignmentPat(a),
PatOutput::Expr(_) => panic!("illegal conversion: Cannot convert {:?} to LVal", &pat),
}
}
}
View on GitHub (pinned to 5176682b65)
Solutions
- Validate before babelify that every `Pat::Expr` in LVal position wraps a `MemberExpr`
- Reject or fix the source: assignment to a non-member expression is a syntax error anyway
- In transforms, construct assignment targets only from valid shapes (Ident patterns or member expressions)
- Wrap babelify in catch_unwind at FFI boundaries so this surfaces as an error, not an abort
Example fix
// before
let estree = module.babelify(); // panics on `for ((a + b) of xs);`
// after - reject invalid targets first
if module.has_invalid_lvals() { return Err(anyhow!("invalid assignment target")); }
let estree = module.babelify(); Defensive patterns
Strategy: type-guard
Validate before calling
use swc_ecma_ast::{Expr, Pat};
fn is_valid_lval(p: &Pat) -> bool {
match p {
Pat::Ident(_) | Pat::Array(_) | Pat::Rest(_) | Pat::Object(_) | Pat::Assign(_) => true,
Pat::Expr(e) => matches!(&**e, Expr::Member(_)),
Pat::Invalid(_) => false,
}
}
// run over for-heads and assignment targets before babelify
fn lvals_ok(m: &swc_ecma_ast::Module) -> bool { /* visitor using is_valid_lval */ true } Type guard
fn expr_is_member(e: &Expr) -> bool {
matches!(e, Expr::Member(_))
} Try / catch
use std::panic::{catch_unwind, AssertUnwindSafe};
catch_unwind(AssertUnwindSafe(|| program.babelify()))
.map_err(|_| anyhow!("invalid assignment target in input"))?; Prevention
- Validate for-in/for-of heads and assignment LHS before estree conversion
- In transforms, build AssignExpr left sides only from valid target shapes
- Reject recovered parses instead of babelifying them
When it happens
Trigger: A for-in/for-of head (`ForHead::Pat` -> ForStmtLeft::LVal at stmt.rs:327) or other LVal slot receives `Pat::Expr` wrapping a non-member expression — recovered code like `for ((a + b) of xs);` or `this() = 1;`, or a transform that put an arbitrary expression on the left of an assignment.
Common situations: Parsing invalid assignment targets with recovery and converting anyway; codemods building AssignExpr with unvalidated left sides; ASTs assembled with swc_ecma_quote without target validation.
Related errors
- illegal conversion: Cannot convert {:?} to PatOutput
- illegal conversion: Cannot convert {:?} to AssignmentPattern
- Cannot convert {p:?} to Param
- illegal conversion: Cannot convert {:?} to ObjectMember
- unable to access unknown nodes
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/d8659d17a4c1d3a8.
Report an issue: GitHub.