{"record":{"id":"71c77f7604a04fad","repo":"JuliusBrussee/caveman","slug":"cave-sandbox-subagent-definition-invalid","errorCode":"cave_sandbox_subagent_definition_invalid","errorMessage":"cave_sandbox_subagent_definition_invalid","messagePattern":"cave_sandbox_subagent_definition_invalid","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/tool-worker.ts","lineNumber":119,"sourceCode":"    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  }\n  const selectedTools = definition.tools.filter((item) => item.name === request.tool);\n  if (selectedTools.length !== 1 || selectedTools[0]!.runtime?.kind === \"subagent\") {\n    throw new Error(\"cave_sandbox_unknown_tool\");\n  }\n  const selected = selectedTools[0]!;\n  if (toolDefinitionSHA256(selected) !== request.toolDefinitionSha256) {\n    throw new Error(\"cave_sandbox_tool_definition_mismatch\");\n  }\n  if (selected.effect !== \"read\" && request.allowSideEffects !== true) {\n    throw new Error(\"cave_sandbox_side_effect_denied\");\n  }\n  const value = await selected.execute(request.params as never, AbortSignal.timeout(selected.timeoutMs));\n  writeResult({ ok: true, value });","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/tool-worker.ts#L101-L137","documentation":"After locating exactly one subagent tool for the current agentPath name, the worker reads `runtime.definition` as the child AgentDefinition. If that child is missing/null or its `kind` is not \"agent\", the worker throws `cave_sandbox_subagent_definition_invalid`. A subagent's runtime must embed a complete, well-kinded agent definition for the walk to continue.","triggerScenarios":"A subagent tool's `runtime.definition` is undefined (built with a reference that was never resolved), points at an object with a different `kind` (e.g. a tool or workflow), or was replaced by a non-definition value (function, string id).","commonSituations":"Hand-assembling a subagent runtime without attaching the child definition; passing a string identifier instead of the built child agent; TypeScript `as AgentDefinition` hiding a wrong-shaped object; serialization stripping nested definitions.","solutions":["Attach the fully built child AgentDefinition to the subagent tool's runtime.definition.","Ensure the child object has `kind: \"agent\"` (built via the agent builder, not a raw tool or partial object).","Pass the built definition object itself, not a name/id reference, when constructing the subagent runtime.","Run graph validation (validateAgentGraph) locally before building to catch malformed nested definitions early."],"exampleFix":"// before\nruntime: { kind: \"subagent\", definition: \"child-agent\" as unknown as AgentDefinition }\n\n// after\nruntime: { kind: \"subagent\", definition: childAgentDefinition }","handlingStrategy":"type-guard","validationCode":"function childDefinitionIsValid(tool: { runtime?: { kind?: string; definition?: unknown } }): boolean {\n  const child = tool.runtime?.definition as AgentDefinition | undefined;\n  return Boolean(child && (child as { kind?: string }).kind === \"agent\");\n}\n// run over every subagent tool before building","typeGuard":"const isAgentDefinition = (v: unknown): v is AgentDefinition =>\n  typeof v === \"object\" && v !== null && (v as { kind?: string }).kind === \"agent\";","tryCatchPattern":null,"preventionTips":["Always attach the fully built child AgentDefinition to a subagent tool's runtime.definition.","Never cast unrelated values with `as AgentDefinition`; construct via the agent builder so `kind` is set.","Pass definition objects, not string ids, into subagent runtimes.","Run graph validation in tests to catch malformed nested definitions before builds."],"tags":["sandbox","subagent","definition","validation"],"backgroundTag":"schema-validation-failed","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"}