JuliusBrussee/caveman · error
cave_claude_subagent_bridge_unavailable
cave_claude_subagent_bridge_unavailable
Error message
cave_claude_subagent_bridge_unavailable
What it means
Thrown by createHarnessToolExecutor() when the tool handed to the package-internal harness bridge is a subagent tool (tool.runtime?.kind === "subagent"). This bridge reuses Pi's exact tool/result policy for a single staged tool; nested agent invocation is not implemented on that path, so it refuses rather than executing the subagent incorrectly.
Source
Thrown at packages/agent/src/runtime.ts:924
entryPath: snapshot.entryPath,
sourceFiles: snapshot.sourceFiles,
executionContext,
dispose: snapshot.dispose,
};
}
/** Package-internal harness bridge. Reuses Pi's exact tool/result policy. */
export function createHarnessToolExecutor(input: {
definition: AgentDefinition;
tool: ToolDefinition;
sandbox: HarnessToolSandbox;
sandboxProfile?: RunOptions["sandboxProfile"];
engineBin?: string;
providerDefinition?: { description: string; input: TSchema };
deferLockedToolResult?: boolean;
}): (params: unknown, signal?: AbortSignal) => Promise<unknown> {
if (input.tool.runtime?.kind === "subagent") {
throw new Error("cave_claude_subagent_bridge_unavailable");
}
const sandboxExecute = input.definition.sandbox === "required"
? (params: unknown, signal?: AbortSignal) => executeSandboxedTool(
input.sandbox.entryPath!,
input.sandbox.sourceFiles,
input.sandbox.stagingRoot!,
input.tool.name,
params,
input.tool.timeoutMs,
true,
input.sandboxProfile,
input.sandbox.executionContext,
toolDefinitionSHA256(input.tool),
signal,
)
: undefined;
const executor = toPiTool(
input.tool,View on GitHub (pinned to 27d5a3981a)
Solutions
- Filter subagent tools out before building harness executors: definition.tools.filter(t => t.runtime?.kind !== "subagent")
- Run subagent tools through the normal agent runtime (run/stream) instead of the harness bridge
- Replace the subagent tool with a plain tool for the harness scenario if nested agent execution is not needed there
Example fix
// before
for (const t of definition.tools) {
executors[t.name] = createHarnessToolExecutor({ definition, tool: t, sandbox });
}
// after
for (const t of definition.tools) {
if (t.runtime?.kind === "subagent") continue;
executors[t.name] = createHarnessToolExecutor({ definition, tool: t, sandbox });
} Defensive patterns
Strategy: type-guard
Validate before calling
const plainTools = definition.tools.filter(t => t.runtime?.kind !== "subagent"); // build harness executors only for plainTools
Type guard
const isSubagentTool = (t: ToolDefinition): boolean =>
(t.runtime as { kind?: string } | undefined)?.kind === "subagent"; Prevention
- Never feed definition.tools wholesale to the harness bridge
- Keep harness scenarios on plain tool(...) definitions
- Route subagent tools through the normal run/stream entry points only
When it happens
Trigger: Calling createHarnessToolExecutor with a ToolDefinition whose runtime.kind === "subagent" — i.e. a tool produced by subagent(...) rather than a plain tool(...).
Common situations: A harness or test that iterates over definition.tools indiscriminately and builds an executor for each, including nested-agent tools; refactoring an agent to use subagents while keeping a custom harness bridge that predates them.
Related errors
- cave_mastra_max_steps_invalid
- cave_harness_upstream_version_mismatch
- caveman-code: not a file: ${input.path}
- cave_harness_build_mismatch
- cave_harness_model_invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/06fd5888fa8230c1.
Report an issue: GitHub.