JuliusBrussee/caveman · error
cave_sandbox_subagent_definition_invalid
cave_sandbox_subagent_definition_invalid
Error message
cave_sandbox_subagent_definition_invalid
What it means
After selecting the subagent tool by name, the worker reads `runtime.definition` and requires it to be a truthy object with `kind === "agent"`. This error means the subagent tool was declared with runtime.kind "subagent" but its embedded definition is missing or not actually an agent definition.
Source
Thrown at packages/agent/src/tool-worker.ts:119
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");
}
const value = await selected.execute(request.params as never, AbortSignal.timeout(selected.timeoutMs));
writeResult({ ok: true, value });View on GitHub (pinned to 27d5a3981a)
Solutions
- Build subagent tools with the framework helper (e.g. subagent(name, definition)) so runtime.definition is always a validated AgentDefinition.
- If constructing manually, assert the embedded object has kind:"agent", tools array, and required fields before spawning.
- Run validateAgentGraph on the root definition in the parent to catch this before the worker does.
Example fix
// before
tool({ name: "child", runtime: { kind: "subagent", definition: childOptions as any } })
// after
tool({ name: "child", runtime: { kind: "subagent", definition: agent({ tools: childTools }) } }) Defensive patterns
Strategy: type-guard
Validate before calling
for (const t of def.tools) {
if (t.runtime?.kind === "subagent") {
const child = t.runtime.definition;
if (!child || child.kind !== "agent") throw new Error(`subagent ${t.name} has invalid definition`);
}
} Type guard
function isValidSubagentRuntime(rt: unknown): rt is { kind: "subagent"; definition: AgentDefinition } {
const r = rt as { kind?: unknown; definition?: { kind?: unknown } } | undefined;
return !!r && r.kind === "subagent" && !!r.definition && r.definition.kind === "agent";
} Prevention
- Always build subagent tools via the framework helper, never hand-assembled runtime objects.
- Run validateAgentGraph(root) in the parent; it catches malformed nested definitions pre-spawn.
When it happens
Trigger: Constructing a subagent runtime manually with `definition: undefined` or a plain options object lacking kind:"agent"; a serialization round-trip that dropped the definition; passing a tool object where a definition was expected.
Common situations: Hand-rolling runtime objects instead of using the framework's subagent() builder; type assertions (`as AgentDefinition`) hiding an undefined; partial object spread that omits the definition key.
Related errors
- cave_sandbox_unknown_subagent
- 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/71c77f7604a04fad.
Report an issue: GitHub.