{"record":{"id":"791faa9a269af499","repo":"JuliusBrussee/caveman","slug":"caveman-build-unresolved-package-dependency-jso","errorCode":null,"errorMessage":"caveman build: unresolved package dependency ${JSON.stringify(dependency)}","messagePattern":"caveman build: unresolved package dependency (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/source-graph.ts","lineNumber":186,"sourceCode":"  const packageJSON = JSON.parse(await readFile(packageJSONPath, \"utf8\")) as {\n    dependencies?: Record<string, unknown>;\n    optionalDependencies?: Record<string, unknown>;\n    peerDependencies?: Record<string, unknown>;\n  };\n  await collectPackageFiles(canonicalRoot, files);\n  const required = new Set(Object.keys(packageJSON.dependencies ?? {}));\n  const optional = new Set([\n    ...Object.keys(packageJSON.optionalDependencies ?? {}),\n    ...Object.keys(packageJSON.peerDependencies ?? {}),\n  ]);\n  for (const dependency of [...new Set([...required, ...optional])].sort()) {\n    try {\n      const childPackageJSON = findPackageJSON(dependency, pathToFileURL(packageJSONPath));\n      if (childPackageJSON === undefined) throw new Error(\"package not found\");\n      await collectPackageClosure(dirname(childPackageJSON), files, visitedRoots);\n    } catch (error) {\n      if (!required.has(dependency)) continue;\n      throw new Error(`caveman build: unresolved package dependency ${JSON.stringify(dependency)}`, {\n        cause: error,\n      });\n    }\n  }\n}\n\nasync function collectPackageFiles(directory: string, files: Set<string>): Promise<void> {\n  const entries = await opendir(directory);\n  for await (const entry of entries) {\n    if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n    const path = resolve(directory, entry.name);\n    if (entry.isDirectory()) {\n      await collectPackageFiles(path, files);\n    } else if (entry.isFile()) {\n      files.add(path);\n    } else if (entry.isSymbolicLink()) {\n      throw new Error(`caveman build: package artifact symlink is not lockable: ${JSON.stringify(path)}`);\n    }","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/source-graph.ts#L168-L204","documentation":"While collecting a package's dependency closure, a dependency listed in package.json's dependencies could not be resolved (its package.json was not found). Required dependencies are hard failures; optional and peer dependencies are skipped silently when unresolvable. The failing dependency name is embedded in the error and the underlying cause is attached.","triggerScenarios":"An installed package's package.json declares a runtime dependency that is missing from node_modules — broken install, pruned store, or a manually-edited package tree.","commonSituations":"Interrupted or partial pnpm/npm install; node_modules copied between machines; a dependency whose transitive install failed; using --no-optional or aggressive pruning that removed a required transitive package.","solutions":["Delete node_modules and lockfile-unfriendly state, then reinstall cleanly (rm -rf node_modules && pnpm install).","Check the named dependency in the error against the lockfile — a lockfile/install mismatch usually explains it.","If the package genuinely needs the dependency only optionally, its maintainers should move it to optionalDependencies; file an issue rather than patching locally."],"exampleFix":"# before\npnpm install --no-optional # or a partial install\n\n# after\nrm -rf node_modules && pnpm install","handlingStrategy":"validation","validationCode":"import { createRequire } from \"node:module\";\nimport { readFileSync } from \"node:fs\";\nfunction requiredDepsResolvable(packageDir: string): void {\n  const pkg = JSON.parse(readFileSync(resolve(packageDir, \"package.json\"), \"utf8\"));\n  const req = createRequire(resolve(packageDir, \"index.js\"));\n  for (const dep of Object.keys(pkg.dependencies ?? {})) {\n    try { req.resolve(`${dep}/package.json`); }\n    catch { throw new Error(`required dependency missing: ${dep}`); }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await buildSourceGraph(root);\n} catch (error) {\n  if (error instanceof Error && error.message.startsWith(\"caveman build: unresolved package dependency\")) {\n    // dependency name is quoted; clean reinstall node_modules\n  } else throw error;\n}","preventionTips":["Clean reinstall when install state looks partial (rm -rf node_modules).","Do not manually delete packages inside node_modules.","Keep the lockfile committed so transitive closures are reproducible."],"tags":["build","dependencies","install","package-closure"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}