swc-project/swc · error
unable to access unknown nodes
Error message
unable to access unknown nodes
What it means
fast_dts's transform_decl matches Decl (Class/Fn/Var/Using/TsEnum/TsModule/TsInterface/TsTypeAlias) to rewrite top-level declarations for .d.ts output. Under the swc_ast_unknown cfg (wasm plugin builds pass `--cfg=swc_ast_unknown`, giving enums an Unknown(tag, payload) variant for kinds unknown to this swc_core) this trailing arm panics: an unknown declaration kind cannot be classified as value or type, so no correct .d.ts can be produced.
Source
Thrown at crates/swc_typescript/src/fast_dts/decl.rs:127
}
for type_element in ts_interface.body.body.iter() {
self.check_ts_signature(type_element);
}
}
Decl::TsTypeAlias(ts_type_alias) => {
if let Some(internal_annotations) = self.internal_annotations.as_ref() {
ts_type_alias.visit_mut_children_with(&mut InternalAnnotationTransformer::new(
internal_annotations,
))
}
if let Some(ts_lit) = ts_type_alias.type_ann.as_ts_type_lit() {
for type_element in ts_lit.members.iter() {
self.check_ts_signature(type_element);
}
}
}
#[cfg(swc_ast_unknown)]
_ => panic!("unable to access unknown nodes"),
}
}
pub(crate) fn transform_variables_declarator(
&mut self,
kind: VarDeclKind,
decl: &mut VarDeclarator,
check_binding: bool,
) {
let pat = match &decl.name {
Pat::Assign(assign_pat) => &assign_pat.left,
_ => &decl.name,
};
if matches!(pat, Pat::Array(_) | Pat::Object(_)) {
pat.bound_names(&mut |ident| {
if !check_binding || self.used_refs.used_as_value(&ident.to_id()) {
self.binding_element_export(ident.span);View on GitHub (pinned to 5176682b65)
Solutions
- Rebuild the plugin against the swc_core version that matches the host @swc/core
- Bump swc_core to the latest release so the declaration decodes concretely
- Pre-scan module items for Decl::Unknown and skip .d.ts emission for that file
- Treat any Unknown-node panic as a signal to resync versions, not to patch the match
Example fix
// before
for item in module.body.iter_mut() {
// fast_dts internally matches Decl; Decl::Unknown -> panic
}
// after (guard, only meaningful under the plugin cfg)
#[cfg(swc_ast_unknown)]
fn module_has_unknown_decl(m: &swc_ecma_ast::Module) -> bool {
m.body.iter().any(|i| matches!(i, swc_ecma_ast::ModuleItem::Stmt(
swc_ecma_ast::Stmt::Decl(swc_ecma_ast::Decl::Unknown(..)))))
}
if !module_has_unknown_decl(&module) { /* run fast_dts */ } Defensive patterns
Strategy: type-guard
Validate before calling
#[cfg(swc_ast_unknown)]
fn module_contains_unknown_decl(m: &swc_ecma_ast::Module) -> bool {
use swc_ecma_ast::*;
m.body.iter().any(|i| matches!(i, ModuleItem::Stmt(
Stmt::Decl(Decl::Unknown(..)))))
} Type guard
#[cfg(swc_ast_unknown)]
fn decl_is_unknown(d: &swc_ecma_ast::Decl) -> bool {
matches!(d, swc_ecma_ast::Decl::Unknown(..))
} Try / catch
let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
run_fast_dts(&mut program)
}));
if out.is_err() {
handler.struct_err("fast_dts skipped file: unknown declaration (version mismatch)").emit();
} Prevention
- Rebuild plugins with the swc_core matching the host @swc/core
- Pre-scan module bodies for Unknown declarations before fast_dts
- Track swc_ecma_ast changelogs for new Decl variants
- Never mix a prebuilt plugin wasm with a newer host without testing
When it happens
Trigger: Running fast_dts on a module whose top-level declaration deserialized as Unknown — a plugin built with --cfg=swc_ast_unknown receiving a Program from a host @swc/core newer than its pinned swc_core, where the host emitted a new Decl variant.
Common situations: Version skew between host and plugin; new declaration kinds added to swc_ecma_ast in a release; plugins distributed as prebuilt wasm not rebuilt after host upgrades.
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/66ebcd051eb2fb8b.
Report an issue: GitHub.