{"record":{"id":"d2c71d731ad84f7e","repo":"swc-project/swc","slug":"paths-from-should-have-only-one-wildcard","errorCode":null,"errorMessage":"`paths.{from}` should have only one wildcard","messagePattern":"`paths\\.(.+?)` should have only one wildcard","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_loader/src/resolvers/tsc.rs","lineNumber":77,"sourceCode":"            #[cfg(debug_assertions)]\n            info!(\n                base_url = tracing::field::display(base_url.display()),\n                \"jsc.paths\"\n            );\n        }\n\n        let mut paths: Vec<(Pattern, Vec<String>)> = paths\n            .into_iter()\n            .map(|(from, to)| {\n                assert!(\n                    !to.is_empty(),\n                    \"value of `paths.{from}` should not be an empty array\",\n                );\n\n                let pos = from.as_bytes().iter().position(|&c| c == b'*');\n                let pat = if from.contains('*') {\n                    if from.as_bytes().iter().rposition(|&c| c == b'*') != pos {\n                        panic!(\"`paths.{from}` should have only one wildcard\")\n                    }\n\n                    Pattern::Wildcard {\n                        prefix: from[..pos.unwrap()].to_string(),\n                    }\n                } else {\n                    assert_eq!(\n                        to.len(),\n                        1,\n                        \"value of `paths.{from}` should be an array with one element because the \\\n                         src path does not contains * (wildcard)\",\n                    );\n\n                    Pattern::Exact(from)\n                };\n\n                (pat, to)\n            })","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_loader/src/resolvers/tsc.rs#L59-L95","documentation":"When building the import resolver from tsconfig.json, each `paths` mapping key may contain at most one `*` wildcard: the resolver models the key as a literal prefix plus a single Pattern::Wildcard. A key containing two or more `*` characters panics during TsconfigResolver construction. This mirrors TypeScript's own rule that paths patterns allow one wildcard.","triggerScenarios":"Constructing NodeImportResolver/TsconfigResolver with a tsconfig.json whose compilerOptions.paths contains a key like \"utils/*/*\"; the code finds the first `*` with position() and the last with rposition() and panics when they differ.","commonSituations":"Monorepo tsconfig files with nested wildcard patterns, configs hand-migrated from webpack/glob-style tooling, generating tsconfig programmatically with glob templates, invalid tsconfig passing a plain tsc check but never exercised for those paths.","solutions":["Rewrite the offending paths key so it contains exactly one `*` (e.g. \"utils/*\" instead of \"utils/*/*\")","Split one multi-wildcard entry into several entries, each anchored on a distinct literal prefix","Run tsc against the same tsconfig as a sanity check; TypeScript rejects multi-wildcard paths keys too","Add a startup assertion that scans paths keys for wildcard count before building the resolver"],"exampleFix":"// tsconfig.json - before\n\"paths\": {\n  \"utils/*/*\": [\"src/utils/*/*\"]\n}\n\n// tsconfig.json - after\n\"paths\": {\n  \"utils/*\": [\"src/utils/*\"],\n  \"utils/deep/*\": [\"src/utils/deep/*\"]\n}","handlingStrategy":"validation","validationCode":"// JS: validate tsconfig paths before building the SWC resolver\nfunction validatePaths(tsconfig) {\n  for (const key of Object.keys(tsconfig.compilerOptions?.paths ?? {})) {\n    const wildcards = [...key].filter(c => c === '*').length;\n    if (wildcards > 1) {\n      throw new Error(`paths key \"${key}\" has ${wildcards} wildcards; only one is allowed`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run `tsc --noEmit` on the same tsconfig to catch invalid paths patterns early","Never generate paths keys from glob templates with multiple stars","Add the wildcard-count check to config validation in CI"],"tags":["tsconfig","paths","resolver","config","wildcard"],"backgroundTag":"tsconfig-paths-invalid","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}