swc-project/swc · error
unable to access unknown nodes
Error message
unable to access unknown nodes
What it means
fast_dts constant-evaluates enum member initializers; inside Expr::Lit it matches Lit keeping Str and Num as ConstantValue and returning None for Null/BigInt/Bool/Regex/JSXText. Under the swc_ast_unknown cfg (set by `--cfg=swc_ast_unknown` in wasm plugin builds) Lit gains an Unknown(tag, payload) variant; this arm panics because an unknown literal kind cannot be evaluated for enum member auto-numbering and string templates.
Source
Thrown at crates/swc_typescript/src/fast_dts/enum.rs:97
});
}
}
fn evaluate(
&self,
expr: &Expr,
enum_name: &Atom,
prev_members: &FxHashMap<Wtf8Atom, ConstantValue>,
) -> Option<ConstantValue> {
match expr {
Expr::Lit(lit) => match lit {
Lit::Str(string) => Some(ConstantValue::String(string.value.clone())),
Lit::Num(number) => Some(ConstantValue::Number(number.clone())),
Lit::Null(_) | Lit::BigInt(_) | Lit::Bool(_) | Lit::Regex(_) | Lit::JSXText(_) => {
None
}
#[cfg(swc_ast_unknown)]
_ => panic!("unable to access unknown nodes"),
},
Expr::Tpl(template) => {
let mut quasis = template.quasis.iter();
let first = quasis.next()?.cooked.as_ref()?;
let mut value = Wtf8Buf::from(first);
for (expr, quasi) in template.exprs.iter().zip(quasis) {
self.evaluate(expr, enum_name, prev_members)?
.push_to(&mut value);
value.push_wtf8(quasi.cooked.as_ref()?);
}
Some(ConstantValue::String(Wtf8Atom::from(&*value)))
}
Expr::Paren(expr) => self.evaluate(&expr.expr, enum_name, prev_members),
Expr::Bin(bin_expr) => self.evaluate_binary_expr(bin_expr, enum_name, prev_members),
Expr::Unary(unary_expr) => {
self.evaluate_unary_expr(unary_expr, enum_name, prev_members)View on GitHub (pinned to 5176682b65)
Solutions
- Rebuild the plugin with the swc_core version matching the host
- Update swc_core to latest so the literal decodes as a known Lit variant
- Skip fast_dts for enums (or files) containing Unknown literals
- Resync versions rather than catching and ignoring the panic
Example fix
# before
# enum E { A = <new-literal-kind> } // host emits Lit::Unknown to old plugin
# fast_dts evaluates initializer -> panic
# after
swc_core = "=aligned-with-host" # rebuild plugin
# literal decodes as Str/Num/...; evaluator returns Some/None normally Defensive patterns
Strategy: type-guard
Validate before calling
#[cfg(swc_ast_unknown)]
fn program_contains_unknown_lit(m: &swc_ecma_ast::Module) -> bool {
use swc_ecma_ast::*;
m.body.iter().any(|i| matches!(i, ModuleItem::Stmt(Stmt::Decl(Decl::TsEnum(e)))
if e.members.iter().any(|mem| matches!(&mem.init, Some(
box Expr::Lit(Lit::Unknown(..)))))))
} Type guard
#[cfg(swc_ast_unknown)]
fn lit_is_unknown(l: &swc_ecma_ast::Lit) -> bool {
matches!(l, swc_ecma_ast::Lit::Unknown(..))
} Try / catch
let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
run_fast_dts(&mut program)
}));
if out.is_err() {
return Err("unknown literal in enum initializer; realign swc_core".into());
} Prevention
- Align plugin swc_core with the host @swc/core and rebuild
- Skip enums whose initializers contain Unknown literals
- Rebuild plugin wasm whenever the host is upgraded
- Log the swc_core version alongside fast_dts runs for debugging
When it happens
Trigger: fast_dts processes a TS enum whose member initializer deserialized as an unknown literal kind — a plugin compiled with --cfg=swc_ast_unknown against a swc_core older than the host that serialized the AST (e.g. a new literal node kind added upstream).
Common situations: Version skew between @swc/core host and plugin swc_core; prebuilt plugin wasm artifacts not rebuilt on host upgrade; new Lit variants in swc_ecma_ast releases.
Related errors
- unable to access unknown nodes
- unable to access unknown nodes
- unable to access unknown nodes
- Duplicated element (${element.key})
- Duplicated element (${elements[j].key})
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/c043fee57fb59227.
Report an issue: GitHub.