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

  1. Validate before babelify that every `Pat::Expr` in LVal position wraps a `MemberExpr`
  2. Reject or fix the source: assignment to a non-member expression is a syntax error anyway
  3. In transforms, construct assignment targets only from valid shapes (Ident patterns or member expressions)
  4. 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

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


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/d8659d17a4c1d3a8. Report an issue: GitHub.