{"record":{"id":"12d0d4501542437b","repo":"JuliusBrussee/caveman","slug":"import-export-not-found","errorCode":null,"errorMessage":"import export not found","messagePattern":"import export not found","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/source-graph.ts","lineNumber":135,"sourceCode":"  // Match TypeScript NodeNext extension substitution. Authored TypeScript uses\n  // runtime-valid .js/.mjs/.cjs specifiers while compiler and loader resolve\n  // their .ts/.mts/.cts sources.\n  if (extension === \".js\") return [`${stem}.ts`, `${stem}.tsx`, base];\n  if (extension === \".mjs\") return [`${stem}.mts`, base];\n  if (extension === \".cjs\") return [`${stem}.cts`, base];\n  return [base];\n}\n\nasync function resolveImportOnlyDependency(specifier: string, importer: string): Promise<string> {\n  const packageName = barePackageName(specifier);\n  const packageJSONPath = resolvePackageJSON(packageName, importer);\n  const packageJSON = JSON.parse(await readFile(packageJSONPath, \"utf8\")) as {\n    exports?: unknown;\n  };\n  const subpath = specifier === packageName ? \".\" : `.${specifier.slice(packageName.length)}`;\n  const target = resolvePackageExport(packageJSON.exports, subpath);\n  if (target === undefined || !target.startsWith(\"./\")) {\n    throw new Error(\"import export not found\");\n  }\n  const packageRoot = dirname(packageJSONPath);\n  const absolute = resolve(packageRoot, target);\n  const relativeTarget = relative(packageRoot, absolute);\n  if (relativeTarget === \"..\" || relativeTarget.startsWith(\"../\") || relativeTarget.startsWith(\"..\\\\\")) {\n    throw new Error(\"package export escapes package root\");\n  }\n  return absolute;\n}\n\nfunction dependencyPackageRoot(specifier: string, importer: string): string {\n  return dirname(resolvePackageJSON(barePackageName(specifier), importer));\n}\n\nfunction resolvePackageJSON(packageName: string, importer: string): string {\n  const packageJSONPath = findPackageJSON(packageName, pathToFileURL(importer));\n  if (packageJSONPath === undefined) throw new Error(\"package not found\");\n  return packageJSONPath;","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/source-graph.ts#L117-L153","documentation":"Thrown by resolveImportOnlyDependency when a package's package.json has no `exports` entry matching the requested import specifier subpath, or the resolved target does not start with \"./\". The library resolves dependencies strictly through the package's declared exports map (Node's export map semantics) and refuses to guess a file path. This means the specifier used in source code is not covered by the package's public export surface.","triggerScenarios":"expandSourceGraph resolves an import-only dependency; resolvePackageExport(exports, subpath) returns undefined (subpath not listed in exports, or exports is a string for a non-\".\" subpath), or the target is not a relative \"./\" path.","commonSituations":"Deep-importing an internal file like `pkg/src/util.js` when exports only exposes \".\"; importing a subpath the package removed in a newer version; package.json lacking an exports field entirely so string-form exports can't serve subpath imports; typos in the subpath.","solutions":["Check the dependency's package.json `exports` map and import only subpaths it actually declares.","Update or pin the dependency version to one that exports the subpath you need.","If you own the dependency, add the missing subpath to its exports map (e.g. \"./util\": \"./dist/util.js\").","If deep import is intentional and legitimate, bypass via a bundler alias or import the file through the package root re-export."],"exampleFix":"// before\nimport { util } from \"somepkg/src/util.js\";\n\n// after\nimport { util } from \"somepkg\"; // use the package's declared export surface","handlingStrategy":"validation","validationCode":"import { readFileSync } from \"node:fs\";\nfunction isExported(pkgDir, name, subpath) {\n  const pkg = JSON.parse(readFileSync(`${pkgDir}/package.json`, \"utf8\"));\n  const key = name === subpath ? \".\" : `.${subpath.slice(name.length)}`;\n  const exp = pkg.exports;\n  if (typeof exp === \"string\" || Array.isArray(exp)) return key === \".\";\n  return !!exp && Object.prototype.hasOwnProperty.call(exp, key);\n}","typeGuard":"function hasExportsField(pkg: unknown): pkg is { exports: Record<string, unknown> } {\n  return typeof pkg === \"object\" && pkg !== null && \"exports\" in pkg && typeof (pkg as any).exports === \"object\";\n}","tryCatchPattern":"try {\n  await graph.expand();\n} catch (e) {\n  if (e instanceof Error && e.message === \"import export not found\") {\n    console.error(\"Specifier not covered by the package exports map; fix the import or the exports field.\");\n  }\n  throw e;\n}","preventionTips":["Only import subpaths listed in the dependency's exports map (check its package.json).","Pin dependency versions so exports surfaces don't shift under you.","Prefer root or re-exported imports over deep imports."],"tags":["module-resolution","exports-map","build"],"backgroundTag":"resource-not-found","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}