JuliusBrussee/caveman · error

import export not found

Error message

import export not found

What it means

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.

Solutions

  1. Check the dependency's package.json `exports` map and import only subpaths it actually declares.
  2. Update or pin the dependency version to one that exports the subpath you need.
  3. If you own the dependency, add the missing subpath to its exports map (e.g. "./util": "./dist/util.js").
  4. If deep import is intentional and legitimate, bypass via a bundler alias or import the file through the package root re-export.

Example fix

// before
import { util } from "somepkg/src/util.js";

// after
import { util } from "somepkg"; // use the package's declared export surface
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync } from "node:fs";
function isExported(pkgDir, name, subpath) {
  const pkg = JSON.parse(readFileSync(`${pkgDir}/package.json`, "utf8"));
  const key = name === subpath ? "." : `.${subpath.slice(name.length)}`;
  const exp = pkg.exports;
  if (typeof exp === "string" || Array.isArray(exp)) return key === ".";
  return !!exp && Object.prototype.hasOwnProperty.call(exp, key);
}

Type guard

function hasExportsField(pkg: unknown): pkg is { exports: Record<string, unknown> } {
  return typeof pkg === "object" && pkg !== null && "exports" in pkg && typeof (pkg as any).exports === "object";
}

Try / catch

try {
  await graph.expand();
} catch (e) {
  if (e instanceof Error && e.message === "import export not found") {
    console.error("Specifier not covered by the package exports map; fix the import or the exports field.");
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/12d0d4501542437b. Report an issue: GitHub.

Appendix: source

Thrown at packages/agent/src/source-graph.ts:135

  // Match TypeScript NodeNext extension substitution. Authored TypeScript uses
  // runtime-valid .js/.mjs/.cjs specifiers while compiler and loader resolve
  // their .ts/.mts/.cts sources.
  if (extension === ".js") return [`${stem}.ts`, `${stem}.tsx`, base];
  if (extension === ".mjs") return [`${stem}.mts`, base];
  if (extension === ".cjs") return [`${stem}.cts`, base];
  return [base];
}

async function resolveImportOnlyDependency(specifier: string, importer: string): Promise<string> {
  const packageName = barePackageName(specifier);
  const packageJSONPath = resolvePackageJSON(packageName, importer);
  const packageJSON = JSON.parse(await readFile(packageJSONPath, "utf8")) as {
    exports?: unknown;
  };
  const subpath = specifier === packageName ? "." : `.${specifier.slice(packageName.length)}`;
  const target = resolvePackageExport(packageJSON.exports, subpath);
  if (target === undefined || !target.startsWith("./")) {
    throw new Error("import export not found");
  }
  const packageRoot = dirname(packageJSONPath);
  const absolute = resolve(packageRoot, target);
  const relativeTarget = relative(packageRoot, absolute);
  if (relativeTarget === ".." || relativeTarget.startsWith("../") || relativeTarget.startsWith("..\\")) {
    throw new Error("package export escapes package root");
  }
  return absolute;
}

function dependencyPackageRoot(specifier: string, importer: string): string {
  return dirname(resolvePackageJSON(barePackageName(specifier), importer));
}

function resolvePackageJSON(packageName: string, importer: string): string {
  const packageJSONPath = findPackageJSON(packageName, pathToFileURL(importer));
  if (packageJSONPath === undefined) throw new Error("package not found");
  return packageJSONPath;

View on GitHub (pinned to 3ee70a1026)