swc-project/swc · error
unable to access unknown nodes
Error message
unable to access unknown nodes
What it means
infer_type_from_expr (crates/swc_typescript/src/fast_dts/inferrer.rs) infers a .d.ts type from expressions such as parameter defaults and exported initializers; for `Expr::Lit` it maps literal kinds to keyword types (string/bool/number/bigint/null). Under `--cfg swc_ast_unknown`, a literal kind this build does not recognize decodes to `Unknown(tag, value)` and the catch-all arm panics, since no keyword type can be derived from an opaque node. The root cause is always an AST produced by a different swc_ecma_ast version crossing a serialization boundary.
Source
Thrown at crates/swc_typescript/src/fast_dts/inferrer.rs:28
util::types::{ts_keyword_type, type_ann},
FastDts,
};
impl FastDts {
pub(crate) fn infer_type_from_expr(&mut self, e: &Expr) -> Option<Box<TsType>> {
match e {
Expr::Ident(ident) if ident.sym.as_str() == "undefined" => {
Some(ts_keyword_type(TsKeywordTypeKind::TsUndefinedKeyword))
}
Expr::Lit(lit) => match lit {
Lit::Str(_) => Some(ts_keyword_type(TsKeywordTypeKind::TsStringKeyword)),
Lit::Bool(_) => Some(ts_keyword_type(TsKeywordTypeKind::TsBooleanKeyword)),
Lit::Num(_) => Some(ts_keyword_type(TsKeywordTypeKind::TsNumberKeyword)),
Lit::BigInt(_) => Some(ts_keyword_type(TsKeywordTypeKind::TsBigIntKeyword)),
Lit::Null(_) => Some(ts_keyword_type(TsKeywordTypeKind::TsNullKeyword)),
Lit::Regex(_) | Lit::JSXText(_) => None,
#[cfg(swc_ast_unknown)]
_ => panic!("unable to access unknown nodes"),
},
Expr::Tpl(_) => Some(ts_keyword_type(TsKeywordTypeKind::TsStringKeyword)),
Expr::Fn(fn_expr) => self.transform_fn_to_ts_type(
&fn_expr.function,
fn_expr.ident.as_ref().map(|ident| ident.span),
),
Expr::Arrow(arrow_expr) => self.transform_arrow_expr_to_ts_type(arrow_expr),
Expr::Array(arr) => {
self.array_inferred(arr.span);
Some(ts_keyword_type(TsKeywordTypeKind::TsUnknownKeyword))
}
Expr::Object(obj) => self.transform_object_to_ts_type(obj, false),
Expr::Class(class) => {
self.inferred_type_of_class_expression(class.span());
Some(ts_keyword_type(TsKeywordTypeKind::TsUnknownKeyword))
}
Expr::Paren(expr) => self.infer_type_from_expr(&expr.expr),
Expr::TsNonNull(non_null) => self.infer_type_from_expr(&non_null.expr),View on GitHub (pinned to 5176682b65)
Solutions
- Unify the swc_core/swc_ecma_ast version between the serializer and the swc_typescript build, then rebuild both.
- Upgrade swc_typescript/swc_core so the new literal kind is known and maps to a real TsType instead of Unknown.
- Re-parse source text in the same process before FastDts::transform rather than reusing a foreign AST.
- Treat --cfg swc_ast_unknown builds as version-sensitive: rebuild/re-deploy them whenever the producing side is upgraded.
Example fix
// before: two crates resolve different swc_ecma_ast versions
# Cargo.toml
swc_typescript = "9"
swc_ecma_ast = "0.118" # newer than what swc_typescript was built for
// after: let swc_core drive every AST crate version
swc_core = { version = "=16.0.0", features = ["ecma_ast", "typescript"] } Defensive patterns
Strategy: type-guard
Validate before calling
// Before inferring types from deserialized default values:
#[cfg(swc_ast_unknown)]
fn default_value_lits_known(params: &[Param]) -> bool {
params.iter().all(|p| match &p.pat {
Pat::Assign(a) => expr_lits_known(&a.right),
_ => true,
})
}
#[cfg(swc_ast_unknown)]
fn expr_lits_known(e: &Expr) -> bool {
!matches!(e, Expr::Lit(l) if matches!(l, Lit::Unknown(..)))
} Type guard
#[cfg(swc_ast_unknown)]
fn lit_is_known(l: &Lit) -> bool {
!matches!(l, Lit::Unknown(..))
} Try / catch
use std::panic::{catch_unwind, AssertUnwindSafe};
let issues = catch_unwind(AssertUnwindSafe(|| dts.transform(&mut program)))
.map_err(|p| format!("fast_dts: {}", p.downcast_ref::<&str>().unwrap_or(&"panic")))?; Prevention
- Align swc_core versions between AST serializer and consumer before running fast_dts on deserialized input.
- In multi-process pipelines, ship both endpoints from the same build; never mix binaries from different release trains.
- Re-parse from source when the incoming AST's provenance/version is unknown.
When it happens
Trigger: FastDts infers a type from a default value or exported expression (e.g. `export const x = <newLiteralKind>`) whose literal node tag is unknown to this build — a Lit variant added in a newer swc_ecma_ast and deserialized into this older binary.
Common situations: Wasm plugins built against an older swc_core receiving AST from a newer @swc/core host; CI checks compiled with RUSTFLAGS="--cfg swc_ast_unknown" exercising newer recorded fixtures; multi-process pipelines that hand serialized ASTs between binaries built at different times.
Related errors
- unable to access unknown nodes
- unable to access unknown nodes
- unable to access unknown nodes
- unable to access unknown nodes
- unable to access unknown nodes
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/9e801d581527ba17.
Report an issue: GitHub.