JuliusBrussee/caveman · error
package not found
Error message
package not found
What it means
resolvePackageJSON walks package.json files up from the importer looking for the named package and throws "package not found" when none locates it. This is the resolution step behind bare-import handling in the source graph: before a dependency's closure can be collected, its physical package root must be found. The error usually surfaces as the cause of the more specific caveman build errors.
Source
Thrown at packages/agent/src/source-graph.ts:152
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;
}
async function collectPackageClosure(
packageRoot: string,
files: Set<string>,
visitedRoots: Set<string>,
): Promise<void> {
const canonicalRoot = await realpath(packageRoot);
if (visitedRoots.has(canonicalRoot)) return;
visitedRoots.add(canonicalRoot);
// Resolve dependency edges from the physical package location. pnpm exposes
// the project dependency as a symlink, while its private dependency links
// live beside the physical package under node_modules/.pnpm.
const packageJSONPath = resolve(canonicalRoot, "package.json");
const packageJSON = JSON.parse(await readFile(packageJSONPath, "utf8")) as {
dependencies?: Record<string, unknown>;
optionalDependencies?: Record<string, unknown>;View on GitHub (pinned to 27d5a3981a)
Solutions
- Install dependencies (pnpm install) so the package exists in node_modules near the importer.
- Declare the package as a direct dependency of the importing package — pnpm's isolated layout hides undeclared packages.
- Verify the package name in the specifier matches the installed package's declared name.
Example fix
# before: import "left-pad" without declaring it (works only via hoisting) # after pnpm add left-pad
Defensive patterns
Strategy: validation
Validate before calling
import { createRequire } from "node:module";
function packageResolvable(pkg: string, importer: string): boolean {
try {
createRequire(importer).resolve(`${pkg}/package.json`);
return true;
} catch { return false; }
} Try / catch
try {
await buildSourceGraph(root);
} catch (error) {
const isPkgMissing = (e: unknown) => e instanceof Error && e.message === "package not found";
if (isPkgMissing(error) || isPkgMissing((error as Error)?.cause)) {
// install the missing package or declare it as a direct dependency
} else throw error;
} Prevention
- Declare every imported package as a direct dependency — pnpm's layout hides undeclared ones.
- Reinstall after pulling changes that touch dependencies.
- Treat "package not found" as a cause: read error.cause to find which specifier failed.
When it happens
Trigger: dependencyPackageRoot() is called for a bare specifier whose package is not present in any node_modules reachable from the importing file.
Common situations: Dependency not installed (fresh clone without install), pnpm strict node_modules where an undeclared package is not visible to the importer, or a package.json name mismatch after a rename.
Related errors
- caveman build: unresolved source dependency ${JSON.stringify
- caveman build: unresolved relative source import ${JSON.stri
- caveman build: unresolved package dependency ${JSON.stringif
- caveman build: dataResidency is not enforced yet; refusing t
- caveman build: requiredFixturePassRate must be in (0,1]
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/12414e210e6ab3dd.
Report an issue: GitHub.