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

  1. Filter subagent tools out before building harness executors: definition.tools.filter(t => t.runtime?.kind !== "subagent")
  2. Run subagent tools through the normal agent runtime (run/stream) instead of the harness bridge
  3. 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

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


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/06fd5888fa8230c1. Report an issue: GitHub.