{"record":{"id":"5f40da19b2e497d1","repo":"JuliusBrussee/caveman","slug":"cave-sandbox-unknown-subagent","errorCode":"cave_sandbox_unknown_subagent","errorMessage":"cave_sandbox_unknown_subagent","messagePattern":"cave_sandbox_unknown_subagent","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/tool-worker.ts","lineNumber":116,"sourceCode":"      !/^[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  }\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\");","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/tool-worker.ts#L98-L134","documentation":"While walking request.agentPath (the chain of subagent delegations from the root definition to the tool's owning agent), the worker filters the current definition's tools for one with the given name AND `runtime.kind === \"subagent\"`. If the filter does not yield exactly one match, it throws `cave_sandbox_unknown_subagent`. The parent's delegation path must be exactly reproducible from the definitions the worker imported.","triggerScenarios":"request.agentPath names a tool that does not exist on the current definition, exists but is not a subagent-runtime tool, or exists as multiple tools with the same name at that level (zero or >1 subagent matches).","commonSituations":"Duplicate tool names in an agent definition (two tools registered under one name); the path was computed against an older definition version while the entry module now differs; a typo or rename in a nested tool name; a plain (non-subagent) tool mistakenly listed in agentPath.","solutions":["Ensure every tool name within an agent definition is unique; rename duplicated tools.","Regenerate the delegation path from the current definition (re-run build) so agentPath matches the imported graph.","Verify each name in agentPath refers to a tool whose runtime.kind is exactly \"subagent\".","Fix typos/renames so the nested tool name in the path matches the definition."],"exampleFix":"// before\ntools: [subagentTool(\"delegate\", childA), subagentTool(\"delegate\", childB)]\n\n// after\ntools: [subagentTool(\"delegate_to_a\", childA), subagentTool(\"delegate_to_b\", childB)]","handlingStrategy":"validation","validationCode":"// Verify each hop of the delegation path resolves to exactly one subagent tool\nlet def = rootDefinition;\nfor (const name of agentPath) {\n  const matches = def.tools.filter((t) => t.name === name && t.runtime?.kind === \"subagent\");\n  if (matches.length !== 1) throw new Error(`agentPath hop '${name}' does not resolve to exactly one subagent`);\n  def = matches[0]!.runtime!.definition as AgentDefinition;\n}","typeGuard":"const isSubagentTool = (t: unknown): t is { name: string; runtime: { kind: \"subagent\"; definition: AgentDefinition } } =>\n  typeof t === \"object\" && t !== null &&\n  (t as any).runtime?.kind === \"subagent\" &&\n  Boolean((t as any).runtime.definition);","tryCatchPattern":null,"preventionTips":["Keep tool names unique within every agent definition.","Let the framework compute agentPath (don't hand-assemble delegation paths).","Re-run build after any tool rename so stored paths match the current graph.","Validate the graph with validateAgentGraph before spawning to catch dangling names early."],"tags":["sandbox","subagent","routing","validation"],"backgroundTag":"resource-not-found","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"}