JuliusBrussee/caveman · error
cave_sandbox_unknown_subagent
cave_sandbox_unknown_subagent
Error message
cave_sandbox_unknown_subagent
What it means
While walking request.agentPath from the root agent inward, the worker filters the current definition's tools for one whose name matches the path element AND whose runtime.kind is "subagent". If zero or more than one tool matches, the delegation path is invalid and the worker refuses to descend.
Source
Thrown at packages/agent/src/tool-worker.ts:116
!/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(request.tool) ||
typeof request.allowSideEffects !== "boolean" ||
typeof request.allowNetwork !== "boolean") {
throw new Error("cave_sandbox_request_invalid");
}
if (request.allowNetwork !== true) installNetworkDeny();
const imported = await import(request.entry) as { default?: AgentDefinition; agent?: AgentDefinition };
let definition = imported.default ?? imported.agent;
if (!definition || definition.kind !== "agent") throw new Error("cave_sandbox_agent_export_missing");
validateAgentGraph(definition);
if (agentDefinitionSHA256(definition) !== request.rootDefinitionSha256) {
throw new Error("cave_sandbox_definition_mismatch");
}
const visited = new Set<AgentDefinition>([definition]);
for (const name of request.agentPath) {
const delegated = definition.tools.filter((item) =>
item.name === name && item.runtime?.kind === "subagent"
);
if (delegated.length !== 1) throw new Error("cave_sandbox_unknown_subagent");
const child = delegated[0]!.runtime!.definition as AgentDefinition;
if (!child || child.kind !== "agent") {
throw new Error("cave_sandbox_subagent_definition_invalid");
}
if (visited.has(child)) throw new Error("cave_sandbox_subagent_cycle");
visited.add(child);
definition = child;
}
const selectedTools = definition.tools.filter((item) => item.name === request.tool);
if (selectedTools.length !== 1 || selectedTools[0]!.runtime?.kind === "subagent") {
throw new Error("cave_sandbox_unknown_tool");
}
const selected = selectedTools[0]!;
if (toolDefinitionSHA256(selected) !== request.toolDefinitionSha256) {
throw new Error("cave_sandbox_tool_definition_mismatch");
}
if (selected.effect !== "read" && request.allowSideEffects !== true) {
throw new Error("cave_sandbox_side_effect_denied");View on GitHub (pinned to 27d5a3981a)
Solutions
- Check the agent's tools array contains exactly one subagent-runtime tool with the path element's name.
- Rename duplicates so every subagent tool name is unique within its parent definition.
- Regenerate/re-derive agentPath after editing tool names, and re-run so the digest checks pass with the new graph.
Example fix
// before
const tools = [subagent("research", researchDef), subagent("research", otherDef)]; // duplicate name
// after
const tools = [subagent("research", researchDef), subagent("research_alt", otherDef)]; Defensive patterns
Strategy: validation
Validate before calling
function resolveSubagent(def: AgentDefinition, name: string): AgentDefinition | null {
const matches = def.tools.filter((t) => t.name === name && t.runtime?.kind === "subagent");
return matches.length === 1 ? (matches[0].runtime!.definition as AgentDefinition) : null;
} Type guard
function hasUniqueSubagent(def: { tools: { name: string; runtime?: { kind?: string } }[] }, name: string): boolean {
return def.tools.filter((t) => t.name === name && t.runtime?.kind === "subagent").length === 1;
} Prevention
- Enforce unique tool names per definition at build time.
- Validate the full agentPath walk in the parent before spawning the worker.
When it happens
Trigger: agentPath names a tool that exists but is a normal tool (runtime.kind !== "subagent"); the name matches no tool at all; two subagent tools share the same name so `delegated.length !== 1`; a typo or renamed subagent in the path.
Common situations: Renaming a subagent tool without updating the path the parent recorded; duplicate tool names inside one agent's tools array (e.g. copy-pasted tool definitions); the parent's path was built against an older definition snapshot.
Related errors
- cave_sandbox_subagent_definition_invalid
- cave_sandbox_subagent_cycle
- cave_host_sandbox_nested_under_required
- cave_sandbox_agent_export_missing
- cave_sandbox_definition_mismatch
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/5f40da19b2e497d1.
Report an issue: GitHub.