JuliusBrussee/caveman · error · Error
caveman agent: entry must export default agent()
Error message
caveman agent: entry must export default agent()
What it means
Thrown by `agentFromImported` while loading the agent entry module (`loadAgent`). The module must export the agent definition as `default` or as a named `agent` export, and that object must carry `kind: "agent"`. Anything else — a module exporting a function, a builder result without the kind tag, or no relevant export at all — fails with this message.
Source
Thrown at packages/agent/src/cli.ts:1383
const configured = [
process.env.ANTHROPIC_API_KEY && "anthropic/claude-haiku-4-5",
process.env.OPENAI_API_KEY && "openai/gpt-5.4-mini",
(process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY) && "google/gemini-2.5-flash",
].filter((value): value is string => typeof value === "string");
if (configured.length !== 1) {
throw new Error("caveman build: set CAVE_MODEL when zero or multiple provider credentials exist");
}
return configured[0]!;
}
async function loadAgent(path: string): Promise<AgentDefinition> {
return agentFromImported(await importFresh(path));
}
function agentFromImported(imported: unknown): AgentDefinition {
const exported = imported as { default?: AgentDefinition; agent?: AgentDefinition };
const definition = exported.default ?? exported.agent;
if (!definition || definition.kind !== "agent") throw new Error("caveman agent: entry must export default agent()");
return definition;
}
async function readLock(root: string): Promise<CaveBuildLock> {
return parseCaveBuildLock(JSON.parse(await readFile(resolve(root, ".caveman/agent.lock.json"), "utf8")));
}
function importFresh(path: string): Promise<unknown> {
return import(`${pathToFileURL(path).href}?cave=${Date.now()}-${crypto.randomUUID()}`);
}
function isEval(value: unknown): value is EvalDefinition {
return value !== null && typeof value === "object" && (value as { kind?: unknown }).kind === "eval";
}
function fixtureInput(value: unknown): string {
return typeof value === "string" ? value : JSON.stringify(value);
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Change the entry to `export default agent({...})` — call the builder and export its returned definition.
- If using a named export, use exactly `export const agent = ...`.
- Only use the framework's `agent()` builder to produce definitions; hand-made objects lack the `kind: "agent"` tag.
- Confirm `config.entry` points at the intended file and that any barrel re-export preserves `default`.
Example fix
// before
export const myAgent = agent({ ... });
// after
export default agent({ ... });
// or: export const agent = agent({ ... }); Defensive patterns
Strategy: type-guard
Validate before calling
function moduleExportsAgentDefinition(mod: Record<string, unknown>): boolean {
const def = (mod.default ?? mod.agent) as { kind?: unknown } | undefined;
return !!def && def.kind === "agent";
}
// const mod = await import(entryPath); assert moduleExportsAgentDefinition(mod); Type guard
function isAgentDefinition(v: unknown): v is { kind: "agent" } {
return typeof v === "object" && v !== null && (v as { kind?: unknown }).kind === "agent";
} Try / catch
try {
await build(args);
} catch (error) {
if (error instanceof Error && error.message === "caveman agent: entry must export default agent()") {
// change entry to `export default agent({...})` (call the builder) and retry
} else throw error;
} Prevention
- Always `export default agent({...})` — invoke the builder, don't export the factory.
- Avoid barrel re-exports for the entry; point config.entry at the defining module.
- Only build definitions with the framework agent() builder so `kind` is set.
When it happens
Trigger: `config.entry` points at a module whose exports are neither `default` nor `agent`, or whose exported value lacks `kind === "agent"` — e.g. `export const agent = () => buildAgent(...)` (exports a factory function, not a definition) or `export default tool({...})`.
Common situations: Exporting the factory instead of calling it (`export default agent` vs `export default agent()`); renaming exports; an entry file that re-exports from a barrel that drops the default; definitions built by hand rather than the `agent()` builder so `kind` was never set.
Related errors
- caveman build: dataResidency is not enforced yet; refusing t
- caveman build: requiredFixturePassRate must be in (0,1]
- caveman build: qualityRetention must be in (0,1]
- caveman build: config must use strict lock and required sand
- caveman build: invalid .caveman/provider.json
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/3131f1737691531a.
Report an issue: GitHub.