JuliusBrussee/caveman · error
caveman build: unresolved source dependency
Error message
caveman build: unresolved source dependency ${JSON.stringify(specifier)} What it means
During 'caveman build' the source-graph walker resolves bare (package) import specifiers to files on disk. It first tries Node's createRequire().resolve, then a fallback resolver for import-only dependencies; if both fail, the dependency cannot be traced to source and this error is thrown with the specifier quoted and the original require error as cause.
Solutions
- Install the missing dependency (npm/pnpm install) so createRequire can resolve it
- If it's a workspace package, link it properly (workspaces config / pnpm link) or build its dist output
- Check package.json 'exports' of the dependency — a specifier pointing to a non-exported subpath will fail resolution
- Verify the specifier spelling against the actual package name
Example fix
// before
import { helper } from '@acme/utils'; // not installed
// after
$ npm install @acme/utils
import { helper } from '@acme/utils'; Defensive patterns
Strategy: validation
Validate before calling
import { createRequire } from 'module';
try {
createRequire(importerPath).resolve(specifier);
} catch {
throw new Error(`Install missing dependency: ${specifier}`);
} Try / catch
try {
await build({ files: sourceFiles(entry) });
} catch (e) {
const m = /unresolved source dependency (.+)/.exec(e.message);
if (m) console.error(`npm install ${JSON.parse(m[1])}`);
else throw e;
} Prevention
- Run npm/pnpm install before builds (CI: cache + install step)
- Keep monorepo workspace links consistent
- Validate import specifiers with a linter (no unresolved imports)
When it happens
Trigger: expandSourceGraph (via sourceFiles/graph/files) encounters a bare specifier whose package cannot be resolved from the importing file's path — package not installed, export map hides the entry, or monorepo workspace not linked.
Common situations: Forgetting 'npm/pnpm install' after adding a dependency; workspace package not linked in a monorepo; dependency only importable at runtime (bundled/aliased) so Node resolution fails; typos in the import specifier.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- caveman build: aliased source loader is not lockable in
- caveman build: computed source dependency is not lockable in
- caveman build: unresolved package dependency
- caveman build: unresolved relative source import
- import export not found
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/409591381331725d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/agent/src/source-graph.ts:57
...esmSourceSpecifiers(typescript.lexableSource, path),
...typescript.specifiers,
...legacySourceSpecifiers(source, path, code),
]);
for (const specifier of specifiers) {
if (BUILTINS.has(specifier)) continue;
const bare = !specifier.startsWith(".");
if (bare && !includeBareDependencies) continue;
let base: string;
let packageRoot: string | undefined;
if (bare) {
packageRoot = dependencyPackageRoot(specifier, path);
try {
base = createRequire(path).resolve(specifier);
} catch (requireError) {
try {
base = await resolveImportOnlyDependency(specifier, path);
} catch {
throw new Error(
`caveman build: unresolved source dependency ${JSON.stringify(specifier)}`,
{ cause: requireError },
);
}
}
} else {
base = resolve(dirname(path), specifier);
}
const candidates = extname(base)
? explicitImportCandidates(base, path)
: [
base,
...RESOLUTION_EXTENSIONS.map((extension) => base + extension),
...SOURCE_EXTENSIONS.map((extension) => resolve(base, `index${extension}`)),
];
let found: string | undefined;
for (const candidate of candidates) {
try {View on GitHub (pinned to 3ee70a1026)