swc-project/swc · error
internal error: entered unreachable code
Error message
internal error: entered unreachable code
What it means
emit_simple_block prints the delimiters of a CSS simple block by matching the opening token against '[', '(' and '{'. Any other token reaches unreachable!(), i.e. the AST holds a SimpleBlock whose name is not a bracket token. The standard swc_css_parser cannot produce such a node, so this indicates a programmatically built or mutated AST, or a parser/codegen version mismatch.
Source
Thrown at crates/swc_css_codegen/src/lib.rs:1237
write_str!(self, n.span, &minified);
} else if let Some(raw) = &n.raw {
write_str!(self, n.span, raw);
} else {
let value = serialize_string(&n.value);
write_str!(self, n.span, &value);
}
}
#[emitter]
fn emit_simple_block(&mut self, n: &SimpleBlock) -> Result {
let (starting, ending) = match n.name.token {
Token::LBracket => ("[", "]"),
Token::LParen => ("(", ")"),
Token::LBrace => ("{", "}"),
_ => {
unreachable!();
}
};
write_raw!(self, lo_span_offset!(n.span, 1), starting);
let len = n.value.len();
for (idx, node) in n.value.iter().enumerate() {
match node {
ComponentValue::ListOfComponentValues(_) | ComponentValue::Declaration(_) => {
if idx == 0 {
formatting_newline!(self);
}
increase_indent!(self);
}
ComponentValue::AtRule(_)
| ComponentValue::QualifiedRule(_)View on GitHub (pinned to 5176682b65)
Solutions
- If you build or mutate CSS AST yourself, normalize SimpleBlock.name.token to one of LBracket/LParen/LBrace before emitting
- Align all swc_css_* crates to the same version
- Dump the offending stylesheet/AST node, isolate it, and report to swc if it came from the parser
Example fix
// before (hand-built AST)
let block = SimpleBlock { name: ComponentValue::Ident(ident("foo")), ..Default::default() };
// after
let block = SimpleBlock { name: ComponentValue::Token(Token { span, token: Token::LBrace }), ..Default::default() }; Defensive patterns
Strategy: validation
Validate before calling
// Validate every SimpleBlock you construct/mutate before emitting
fn block_delims_ok(b: &SimpleBlock) -> bool {
matches!(
b.name.token,
Token::LBracket | Token::LParen | Token::LBrace
)
}
blocks.iter().all(block_delims_ok) Type guard
fn is_emittable_block(b: &SimpleBlock) -> bool {
matches!(b.name.token, Token::LBracket | Token::LParen | Token::LBrace)
} Try / catch
let css = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
let mut c = Codegen::new(); c.build(&stylesheet); c.get()
}));
match css {
Ok(s) => s,
Err(p) if panic_message(&p).contains("unreachable") => {
// fallback: re-serialize via the parser (parse -> emit) to normalize the AST
}
Err(p) => std::panic::resume_unwind(p),
} Prevention
- Keep swc_css_parser/codegen/ast on the same version
- Validate tokens of programmatically built SimpleBlock nodes before emitting
- Round-trip mutated AST through the parser once to normalize it
When it happens
Trigger: Passing swc_css_ast SimpleBlock nodes constructed or altered by external code (deserializers, linters, plugins) whose name token is not LBracket/LParen/LBrace into swc_css_codegen; mixing swc_css_parser and swc_css_codegen from different releases.
Common situations: Postcss-style CSS tooling in Rust that constructs or edits AST nodes; deserializing CSS ASTs from JSON without validating token kinds; partial crate upgrades.
Related errors
- Unknown statement type: ${(stmt as any).type
- Method visitTsType not implemented.
- empty expression container
- Non-computed member expression with property other than iden
- internal error: entered unreachable code
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/3c920cdd6328aa72.
Report an issue: GitHub.