swc-project/swc · error
Cannot transform sum children into CalcProduct
Error message
Cannot transform sum children into CalcProduct
What it means
While minifying, swc_css_minifier re-serializes folded calc() trees. Converting a CalcSum's children back into CalcProductOrOperator it expects each CalcOperatorNode to be Add or Negate; any other operator shape hits unreachable!(), flagging a calc AST the serializer cannot express — normally produced by an earlier folding bug or by externally constructed calc nodes.
Source
Thrown at crates/swc_css_minifier/src/compressor/calc_sum.rs:890
}));
expr.push(serialize_calc_node_into_calc_product(calc_node));
}
CalcNode::OperatorNode(op) => match &**op {
CalcOperatorNode::Product(_) => {
expr.push(CalcProductOrOperator::Operator(CalcOperator {
value: CalcOperatorType::Add,
span: Span::dummy_with_cmt(),
}));
expr.push(serialize_calc_node_into_calc_product(calc_node));
}
CalcOperatorNode::Negate(calc_node) => {
expr.push(CalcProductOrOperator::Operator(CalcOperator {
value: CalcOperatorType::Sub,
span: Span::dummy_with_cmt(),
}));
expr.push(serialize_calc_node_into_calc_product(calc_node));
}
_ => unreachable!("Cannot transform sum children into CalcProduct"),
},
}
}
CalcSum {
expressions: expr,
span: Span::dummy_with_cmt(),
}
}
_ => CalcSum {
expressions: vec![serialize_calc_node_into_calc_product(calc_node)],
span: Span::dummy_with_cmt(),
},
},
}
}
fn serialize_calc_node_into_calc_product(calc_node: &CalcNode) -> CalcProductOrOperator {
match calc_node {View on GitHub (pinned to 5176682b65)
Solutions
- Update swc_css_minifier and swc_css_parser together to the same release
- Bisect the stylesheet to the failing calc() expression, simplify it (pre-resolve arithmetic manually), and attach the repro to a swc issue
- If you generate calc ASTs programmatically, round-trip them through the parser's own serialization once to normalize the tree
Example fix
/* before */ width: calc(100% - (10px + 2em) * 3); /* after */ width: calc(100% - 30px - 6em);
Defensive patterns
Strategy: fallback
Validate before calling
// Flag complex calc() expressions so they can be excluded/simplified before minification
fn risky_calc(css: &str) -> bool {
css.matches("calc(").count() > 4 || css.contains("calc(") && css.contains("* 3")
} Try / catch
let min = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| minify(&stylesheet)));
match min {
Ok(v) => v,
Err(p) if panic_message(&p).contains("CalcProduct") => {
// fallback: emit the stylesheet unminified (or skip calc folding) for this file
stylesheet
}
Err(p) => std::panic::resume_unwind(p),
} Prevention
- Keep swc_css_minifier and swc_css_parser on the same release
- Pre-resolve arithmetic in generated calc() where possible
- Ship a build fallback that skips CSS minification on panic instead of failing the release
- Bisect reported failures to a single calc() expression and pin/simplify it
When it happens
Trigger: Minifying stylesheets containing calc() expressions with mixed/nested operators where the internal re-serialization invariant breaks; custom CSS transforms that emit CalcOperatorNode trees directly into the minifier.
Common situations: Aggressive CSS minification on complex calc() like `calc(100% - (10px + 2em) * 3)`; version drift between swc_css_parser and swc_css_minifier; machine-generated stylesheets.
Related errors
- Cannot transform product children into CalcProduct
- Duplicated element (${element.key})
- Duplicated element (${elements[j].key})
- internal error: entered unreachable code
- internal error: entered unreachable code
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/7223c766d64ca461.
Report an issue: GitHub.