{"record":{"id":"ba966bd1b63b5e5e","repo":"JuliusBrussee/caveman","slug":"cave-sandbox-agent-export-missing","errorCode":"cave_sandbox_agent_export_missing","errorMessage":"cave_sandbox_agent_export_missing","messagePattern":"cave_sandbox_agent_export_missing","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/tool-worker.ts","lineNumber":106,"sourceCode":"  const request = await readRequest();\n  if (typeof request.entry !== \"string\" || !Array.isArray(request.agentPath) ||\n      request.agentPath.length > 8 ||\n      request.agentPath.some((item) => typeof item !== \"string\" ||\n        !/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(item)) ||\n      typeof request.rootDefinitionSha256 !== \"string\" ||\n      !/^[a-f0-9]{64}$/.test(request.rootDefinitionSha256) ||\n      typeof request.toolDefinitionSha256 !== \"string\" ||\n      !/^[a-f0-9]{64}$/.test(request.toolDefinitionSha256) ||\n      typeof request.tool !== \"string\" ||\n      !/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(request.tool) ||\n      typeof request.allowSideEffects !== \"boolean\" ||\n      typeof request.allowNetwork !== \"boolean\") {\n    throw new Error(\"cave_sandbox_request_invalid\");\n  }\n  if (request.allowNetwork !== true) installNetworkDeny();\n  const imported = await import(request.entry) as { default?: AgentDefinition; agent?: AgentDefinition };\n  let definition = imported.default ?? imported.agent;\n  if (!definition || definition.kind !== \"agent\") throw new Error(\"cave_sandbox_agent_export_missing\");\n  validateAgentGraph(definition);\n  if (agentDefinitionSHA256(definition) !== request.rootDefinitionSha256) {\n    throw new Error(\"cave_sandbox_definition_mismatch\");\n  }\n  const visited = new Set<AgentDefinition>([definition]);\n  for (const name of request.agentPath) {\n    const delegated = definition.tools.filter((item) =>\n      item.name === name && item.runtime?.kind === \"subagent\"\n    );\n    if (delegated.length !== 1) throw new Error(\"cave_sandbox_unknown_subagent\");\n    const child = delegated[0]!.runtime!.definition as AgentDefinition;\n    if (!child || child.kind !== \"agent\") {\n      throw new Error(\"cave_sandbox_subagent_definition_invalid\");\n    }\n    if (visited.has(child)) throw new Error(\"cave_sandbox_subagent_cycle\");\n    visited.add(child);\n    definition = child;\n  }","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/tool-worker.ts#L88-L124","documentation":"Thrown by the cave sandbox tool worker (packages/agent/src/tool-worker.ts) after it dynamically imports the entry module from the request and finds no usable agent definition. The worker expects `imported.default ?? imported.agent` to be an object with `kind === \"agent\"`. If both exports are missing, undefined, or not marked kind:\"agent\", the run fails closed before any tool executes.","triggerScenarios":"The parent process spawns the worker with request.entry pointing at a module that (a) exports nothing, (b) exports the agent under a different name (e.g. `export const myAgent`), (c) default-exports a plain object/tool without `kind: \"agent\"`, or (d) fails module initialization so the import resolves to an incomplete namespace.","commonSituations":"Refactoring an agent file and renaming its export; a bundled/compiled entry whose default export shape changed between versions; an entry path resolved to a barrel file that re-exports the agent non-default; a stale build artifact from `pnpm build` that no longer matches source.","solutions":["Ensure the entry module has `export default defineAgent(...)` (or `export const agent = ...`) producing an object with kind:\"agent\".","Verify request.entry resolves to the exact file that owns the agent definition, not an index/barrel.","Rebuild the package (`pnpm --dir packages/agent build`) so the worker imports current output rather than a stale artifact.","Check the import succeeds at module top level — a throw during module init surfaces as this or an uncaught code, so run `node -e \"import('./entry').then(m=>console.log(Object.keys(m)))\"` to inspect exports."],"exampleFix":"// before\nexport const researchAgent = { tools: [...] }; // no kind, no default export\n\n// after\nimport { agent } from \"@caveman-ai/agent\";\nexport default agent({ tools: [...] }); // default export, kind: \"agent\"","handlingStrategy":"validation","validationCode":"async function assertAgentEntry(entry: string): Promise<void> {\n  const mod = (await import(entry)) as { default?: unknown; agent?: unknown };\n  const def = mod.default ?? mod.agent;\n  if (!def || (def as { kind?: string }).kind !== \"agent\") {\n    throw new Error(`entry ${entry} lacks a default/agent export with kind \"agent\"`);\n  }\n}","typeGuard":"function isAgentDefinition(v: unknown): v is { kind: \"agent\"; tools: unknown[] } {\n  return !!v && typeof v === \"object\" && (v as { kind?: unknown }).kind === \"agent\";\n}","tryCatchPattern":"try { await import(entry); } catch (e) { /* treat any module-shape failure as fatal; do not spawn worker with a suspect entry */ }","preventionTips":["Standardize on `export default agent({...})` in every entry file.","Run validateAgentGraph on the imported definition in the parent before spawning the sandbox worker.","Add a unit test per entry module asserting its default export has kind:\"agent\"."],"tags":["sandbox","agent-definition","esm-import","cave"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}