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

  1. Update swc_css_minifier and swc_css_parser together to the same release
  2. Bisect the stylesheet to the failing calc() expression, simplify it (pre-resolve arithmetic manually), and attach the repro to a swc issue
  3. 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

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


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