{"record":{"id":"68d48ef82a2107e4","repo":"swc-project/swc","slug":"node-path-provider-does-not-support-using-a","errorCode":null,"errorMessage":"Node path provider does not support using `{:?}` as a target file name","messagePattern":"Node path provider does not support using `(.+?)` as a target file name","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_module/src/path.rs","lineNumber":308,"sourceCode":"                    target.filename = FileName::Real(orig);\n                }\n            }\n        }\n\n        let Resolution {\n            filename: target,\n            slug,\n        } = target;\n        let slug = slug.as_deref().or(orig_slug);\n\n        #[cfg(debug_assertions)]\n        info!(\"Resolved as {target:?} with slug = {slug:?}\");\n\n        let mut target = match target {\n            FileName::Real(v) => v,\n            FileName::Custom(s) => return Ok(self.to_specifier(s.into(), slug)),\n            _ => {\n                unreachable!(\n                    \"Node path provider does not support using `{:?}` as a target file name\",\n                    target\n                )\n            }\n        };\n        let mut base = match base {\n            FileName::Real(v) => Cow::Borrowed(\n                v.parent()\n                    .ok_or_else(|| anyhow!(\"failed to get parent of {v:?}\"))?,\n            ),\n            FileName::Anon => match &self.config.base_dir {\n                Some(v) => Cow::Borrowed(&**v),\n                None => {\n                    if cfg!(target_arch = \"wasm32\") {\n                        panic!(\"Please specify `filename`\")\n                    } else {\n                        Cow::Owned(current_dir().expect(\"failed to get current directory\"))\n                    }","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_module/src/path.rs#L290-L326","documentation":"NodePathProvider::try_resolve_import (swc_ecma_transforms_module) rewrites import specifiers into relative paths after the module resolver runs. The resolved target filename must be FileName::Real (a real path to relativize) or FileName::Custom (a virtual specifier returned verbatim); every other FileName variant (Url, Internal, Anon, ...) hits this unreachable!, i.e. the provider cannot compute a relative path for such a target.","triggerScenarios":"A custom or exotic ImportResolver whose Resolution.filename is FileName::Url (data:/http: style module references) or FileName::Internal/Anon, while jsc.transform.modules (commonjs/amd/systemjs) import rewriting is enabled. Embedders passing an anonymous input file whose resolver echoes Anon back as the target also trip it.","commonSituations":"Bundler/spack-style integrations with resolvers returning URL filenames; virtual-module plugins that mark resolved files with Url/Internal instead of Custom; upgrading swc versions where FileName gained new variants the path provider has not learned.","solutions":["Make your resolver return FileName::Real for on-disk modules and FileName::Custom(specifier) for virtual ones — never Url/Internal as the resolved target filename.","If you control the input, pass a real path (or configure base_dir) so the provider has something to relativize against.","Update swc_ecma_transforms_module; new FileName handling lands over time.","As an embedder, wrap the transform in catch_unwind and degrade to leaving the specifier untouched."],"exampleFix":"// before: resolver returns a URL target -> panic in try_resolve_import\nOk(Resolution { filename: FileName::Url(url), slug: None })\n\n// after: virtual targets use Custom, real files use Real\nOk(Resolution {\n    filename: if is_virtual {\n        FileName::Custom(specifier.clone())\n    } else {\n        FileName::Real(path_buf)\n    },\n    slug: None,\n})","handlingStrategy":"validation","validationCode":"// Validate resolved targets before import rewriting\nuse swc_common::FileName;\nfn usable_target(f: &FileName) -> bool {\n    matches!(f, FileName::Real(_) | FileName::Custom(_))\n}\n// in your resolver hook:\n// assert!(usable_target(&res.filename), \"resolver must return Real or Custom targets\");","typeGuard":"fn is_supported_target(f: &FileName) -> bool { matches!(f, FileName::Real(_) | FileName::Custom(_)) }","tryCatchPattern":"let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    module_transform.apply(cm, &mut program)\n}));\nout.unwrap_or_else(|_| { /* keep original specifiers, log resolver filename variant */ });","preventionTips":["Custom resolvers: return FileName::Real for disk files, FileName::Custom for virtual modules — never Url/Internal.","Test module transforms with your resolver before shipping.","Wrap swc transforms in catch_unwind at FFI boundaries since these failures are panics, not Results."],"tags":["swc","transforms-module","path-resolution","filename","import-rewriting","resolver","panic"],"backgroundTag":"unsupported-filename-type","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}