{"record":{"id":"3131f1737691531a","repo":"JuliusBrussee/caveman","slug":"caveman-agent-entry-must-export-default-agent","errorCode":null,"errorMessage":"caveman agent: entry must export default agent()","messagePattern":"caveman agent: entry must export default agent\\(\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/cli.ts","lineNumber":1383,"sourceCode":"  const configured = [\n    process.env.ANTHROPIC_API_KEY && \"anthropic/claude-haiku-4-5\",\n    process.env.OPENAI_API_KEY && \"openai/gpt-5.4-mini\",\n    (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY) && \"google/gemini-2.5-flash\",\n  ].filter((value): value is string => typeof value === \"string\");\n  if (configured.length !== 1) {\n    throw new Error(\"caveman build: set CAVE_MODEL when zero or multiple provider credentials exist\");\n  }\n  return configured[0]!;\n}\n\nasync function loadAgent(path: string): Promise<AgentDefinition> {\n  return agentFromImported(await importFresh(path));\n}\n\nfunction agentFromImported(imported: unknown): AgentDefinition {\n  const exported = imported as { default?: AgentDefinition; agent?: AgentDefinition };\n  const definition = exported.default ?? exported.agent;\n  if (!definition || definition.kind !== \"agent\") throw new Error(\"caveman agent: entry must export default agent()\");\n  return definition;\n}\n\nasync function readLock(root: string): Promise<CaveBuildLock> {\n  return parseCaveBuildLock(JSON.parse(await readFile(resolve(root, \".caveman/agent.lock.json\"), \"utf8\")));\n}\n\nfunction importFresh(path: string): Promise<unknown> {\n  return import(`${pathToFileURL(path).href}?cave=${Date.now()}-${crypto.randomUUID()}`);\n}\n\nfunction isEval(value: unknown): value is EvalDefinition {\n  return value !== null && typeof value === \"object\" && (value as { kind?: unknown }).kind === \"eval\";\n}\n\nfunction fixtureInput(value: unknown): string {\n  return typeof value === \"string\" ? value : JSON.stringify(value);\n}","sourceCodeStart":1365,"sourceCodeEnd":1401,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/cli.ts#L1365-L1401","documentation":"agentFromImported in packages/agent/src/cli.ts loads the entry module given to 'caveman agent' and accepts either a default export or a named `agent` export that must have kind === 'agent'. If the module has neither export, the export is undefined/null, or the object is not an agent definition, it throws 'caveman agent: entry must export default agent()'.","triggerScenarios":"Running `caveman agent <path>` where the entry file has no default export and no `agent` export, exports something that is not an AgentDefinition (e.g. a plain object without kind: 'agent', or a function), or exports the agent under a different name.","commonSituations":"Authoring an agent file with only `export const myAgent = {...}`; forgetting `export default`; using `export function agent()` (a function, not an object with kind 'agent'); transpilation/bundler output stripping or renaming the export; pointing caveman at a utility module instead of the agent entry.","solutions":["Add `export default { kind: \"agent\", ... }` to the entry file, or export it as `export const agent = { kind: \"agent\", ... }`.","Verify the exported object includes kind: \"agent\" (not a factory function returning it).","Confirm you passed the correct entry file path to `caveman agent` — one that actually defines the agent.","Log the module's keys (`Object.keys(await import(path))`) to see what is actually exported after transpilation.","If using a bundler/TS config, ensure the export is preserved (e.g. no tree-shaking of the default export)."],"exampleFix":"// before\nconst helper = { kind: \"tool\", name: \"x\" };\nexport { helper };\n// after\nconst agent = { kind: \"agent\", name: \"my-agent\", tools: [helper] };\nexport default agent;","handlingStrategy":"type-guard","validationCode":"const mod = await import(entryPath);\nif (!(mod.default ?? mod.agent)) throw new Error(`Entry ${entryPath} has no default/agent export`);","typeGuard":"const isAgentDefinition = (x: unknown): x is AgentDefinition =>\n  typeof x === \"object\" && x !== null && (x as any).kind === \"agent\";","tryCatchPattern":"try {\n  await runAgent(entryPath);\n} catch (e) {\n  if (e.message.includes(\"must export default agent()\")) {\n    console.error(`Entry ${entryPath} must ` + \"export default { kind: 'agent', ... }\");\n  } else throw e;\n}","preventionTips":["Always use `export default` (or `export const agent`) for agent entry files.","Export the definition object itself, not a factory function returning it.","Include kind: \"agent\" on the exported object.","Point caveman at the module that defines the agent, not a helper module."],"tags":["cli","module","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}