swc-project/swc · error
illegal conversion: Cannot convert {:?} to Expr::Lit
Error message
illegal conversion: Cannot convert {:?} to Expr::Lit What it means
Import attribute values must be string literals per the import-attributes spec, and this conversion only maps Lit::Str. If the with-clause object contains a non-string literal value — a number, boolean, null, regex, or BigInt — the inner match panics with 'illegal conversion: Cannot convert ... to Expr::Lit'. The Babel ImportAttribute simply has no field for non-string literal values, so the converter refuses rather than lying about the AST.
Source
Thrown at crates/swc_estree_compat/src/babelify/module_decl.rs:131
_ => panic!(
"illegal conversion: Cannot convert {:?} to Prop",
&prop_or_spread
),
};
let (key, val) = match *prop {
Prop::KeyValue(keyval) => {
let key = match keyval.key {
PropName::Ident(i) => IdOrString::Id(i.babelify(ctx)),
PropName::Str(s) => IdOrString::String(s.babelify(ctx)),
_ => panic!(
"illegal conversion: Cannot convert {:?} to Prop::KeyValue",
&keyval.key
),
};
let val = match *keyval.value {
Expr::Lit(lit) => match lit {
Lit::Str(s) => s.babelify(ctx),
_ => panic!(
"illegal conversion: Cannot convert {:?} to Expr::Lit",
&lit
),
},
_ => panic!(
"illegal conversion: Cannot convert {:?} to Expr::Lit",
&keyval.value
),
};
(key, val)
}
_ => panic!(
"illegal conversion: Cannot convert {:?} to key, value",
&prop
),
};
ImportAttribute {
base: ctx.base(obj_span),View on GitHub (pinned to 5176682b65)
Solutions
- Fix the source: quote the attribute value (`with { type: 'json' }`)
- Pre-validate the with-clause: each value must be Expr::Lit(Lit::Str)
- Report a clear syntax-level error for such files instead of letting babelify panic
- Catch the panic via catch_unwind in batch converters
Example fix
// before
import x from './x.json' with { type: 42 };
// after
import x from './x.json' with { type: 'json' }; Defensive patterns
Strategy: validation
Validate before calling
fn import_attr_values_ok(module: &Module) -> Result<(), String> {
for item in &module.body {
if let ModuleItem::ModuleDecl(ModuleDecl::Import(i)) = item {
if let Some(with) = &i.with {
for p in &with.props {
if let PropOrSpread::Prop(prop) = p {
if let Prop::KeyValue(kv) = &**prop {
if !matches!(&*kv.value, Expr::Lit(lit) if matches!(**lit, Lit::Str(_))) {
return Err("import attribute value must be a string literal".into());
}
}
}
}
}
}
}
Ok(())
} Type guard
fn lit_is_attr_string(l: &Lit) -> bool {
matches!(l, Lit::Str(_))
} Try / catch
let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| program.babelify(&ctx)))
.map_err(|_| anyhow::anyhow!("invalid import attribute value (must be string literal)"))?; Prevention
- Always quote import attribute values
- Validate with-clause values in ingestion pipelines
- Add a lint rule for import attributes if your tool consumes third-party JS
When it happens
Trigger: Parsing and babelifying `import x from './m' with { type: 42 }` or `with { type: true }` — any literal other than a string as the attribute value.
Common situations: Typos where developers drop quotes in the with-clause; codegen emitting unquoted values; malformed inputs hitting AST conversion tooling.
Related errors
- illegal conversion: Cannot convert {:?} to Prop
- illegal conversion: Cannot convert {:?} to Prop::KeyValue
- illegal conversion: Cannot convert {:?} to key, value
- illegal conversion: Cannot convert {:?} to BinaryExprOp
- illegal conversion: Cannot convert {:?} to LogicalExprOp
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/ea9124e65ccd12e6.
Report an issue: GitHub.