swc-project/swc · error
add_effects for class expression
Error message
add_effects for class expression
What it means
`ExprCtx::extract_side_effects_to` in swc_ecma_utils walks an expression to keep only its side-effectful parts; it handles calls, member accesses, unary/seq/assign, tagged templates, etc., but class expressions panic because their side effects (extends clause, computed keys, decorators) are not modeled. The optimizer's expr simplifier and the minifier call it when collapsing member accesses on array literals into sequence expressions.
Source
Thrown at crates/swc_ecma_utils/src/lib.rs:2021
self.extract_side_effects_to(v, *e.expr);
v
});
}
Expr::TaggedTpl(TaggedTpl { tag, tpl, .. }) => {
self.extract_side_effects_to(to, *tag);
tpl.exprs
.into_iter()
.for_each(|e| self.extract_side_effects_to(to, *e));
}
Expr::Tpl(Tpl { exprs, .. }) => {
exprs
.into_iter()
.for_each(|e| self.extract_side_effects_to(to, *e));
}
Expr::Class(ClassExpr { .. }) => unimplemented!("add_effects for class expression"),
Expr::JSXMember(..)
| Expr::JSXNamespacedName(..)
| Expr::JSXEmpty(..)
| Expr::JSXElement(..)
| Expr::JSXFragment(..) => to.push(Box::new(expr)),
Expr::TsTypeAssertion(TsTypeAssertion { expr, .. })
| Expr::TsNonNull(TsNonNullExpr { expr, .. })
| Expr::TsAs(TsAsExpr { expr, .. })
| Expr::TsConstAssertion(TsConstAssertion { expr, .. })
| Expr::TsInstantiation(TsInstantiation { expr, .. })
| Expr::TsSatisfies(TsSatisfiesExpr { expr, .. }) => {
self.extract_side_effects_to(to, *expr)
}
Expr::OptChain(..) => to.push(Box::new(expr)),
Expr::Invalid(..) => unreachable!(),View on GitHub (pinned to d7d7434666)
Solutions
- Disable the triggering optimization: turn off jsc.minify (or the specific simplify/compress pass) for files that hit this
- Refactor class expressions inside array literals into const declarations before the array
- Reduce to a minimal repro and report upstream — the `Expr::Class` arm of extract_side_effects_to needs an implementation
Example fix
// before
const x = [class {}, 1][1];
// after
const _c = class {};
const x = [_c, 1][1]; Defensive patterns
Strategy: try-catch
Type guard
// Rust: detect class expressions inside array literals that may be simplified
fn array_literal_contains_class(e: &Expr) -> bool {
matches!(e, Expr::Array(ArrayLit { elems, .. })
if elems.iter().flatten().any(|el| matches!(&*el.expr, Expr::Class(..))))
} Try / catch
// Rust: isolate minification of untrusted bundles
let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
minify(source, &options)
}));
match out {
Ok(r) => r,
Err(_) => { /* log the panic and fall back to minify with compress disabled for this file */ }
} Prevention
- Provide a fallback path that re-runs files failing under jsc.minify with compress/simplify disabled
- Avoid class expressions as direct array-literal elements in code destined for minification
- Report the input upstream — each panic here is a missing Expr::Class arm in side-effect extraction
When it happens
Trigger: Run the optimizer's simplify pass or jsc.minify compress over code where an array literal containing a class expression is reordered — e.g. `[class {}, x, y][1]` — so preceding elements must be reduced to side effects.
Common situations: Minifying third-party bundles; codebases that register class expressions in arrays (DI containers, metadata registries); enabling member-expression simplification on literals under jsc.minify.compress or the optimizer.
Related errors
AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16).
Data as JSON: /api/errors/6697c936ed19b24c.
Report an issue: GitHub.