JuliusBrussee/caveman · error
cave_tool_sandbox_entry_required
cave_tool_sandbox_entry_required
Error message
cave_tool_sandbox_entry_required: sandboxed tools need entryPath
What it means
Thrown by the package-internal harness bridge prepareHarnessToolSandbox() when the agent graph requires sandboxed tool execution (definition.sandbox === "required" or inherited from an ancestor, with at least one non-subagent tool in the graph) but options.entryPath is undefined. The sandbox stages an immutable copy of the source graph and imports tool workers only from that copy, so it needs an entry point to stage from. Without entryPath there is nothing to sandbox and required-sandbox execution must fail closed rather than run tools unsandboxed.
Source
Thrown at packages/agent/src/runtime.ts:886
/** Package-internal harness bridge. Not exported from package entry point. */
export interface HarnessToolSandbox {
readonly stagingRoot?: string;
readonly entryPath?: string;
readonly sourceFiles: readonly string[];
readonly executionContext: InternalExecutionContext;
dispose(): Promise<void>;
}
/** Package-internal harness bridge. Stages one immutable source graph. */
export async function prepareHarnessToolSandbox(
definition: AgentDefinition,
options: Pick<RunOptions, "rootDir" | "entryPath">,
): Promise<HarnessToolSandbox> {
const executionContext = rootExecutionContext(definition);
if (options.entryPath === undefined &&
requiresSandboxEntry(definition, executionContext.sandboxRequired)) {
throw new Error(
"cave_tool_sandbox_entry_required: sandboxed tools need entryPath",
);
}
if (options.entryPath === undefined) {
return {
sourceFiles: Object.freeze([]),
executionContext,
async dispose() {},
};
}
const rootDir = options.rootDir ?? process.cwd();
const requested = resolve(rootDir, options.entryPath);
const snapshot = await stageSandboxSourceGraph(
rootDir,
requested,
dirname(fileURLToPath(import.meta.url)),
);
return {View on GitHub (pinned to 27d5a3981a)
Solutions
- Pass options.entryPath pointing at the entry module of the source graph to stage, e.g. prepareHarnessToolSandbox(def, { entryPath: "src/main.ts" })
- If the tools genuinely need host access, declare sandbox: "host" on the definition instead of "required" (explicit opt-in; host mode runs closures in-process with no entryPath)
- If sandboxing is not intended, remove sandbox: "required" from the definition and any nested subagent definitions
Example fix
// before
const sandbox = await prepareHarnessToolSandbox(definition, { rootDir });
// after
const sandbox = await prepareHarnessToolSandbox(definition, {
rootDir,
entryPath: "src/tools-entry.ts",
}); Defensive patterns
Strategy: validation
Validate before calling
// Before calling the harness bridge: does the graph need an entry path?
import { readFileSync } from "node:fs";
function graphNeedsEntry(definition: AgentDefinition, inherited = false): boolean {
const required = inherited || definition.sandbox === "required";
return definition.tools.some(t =>
t.runtime?.kind !== "subagent" ? required
: graphNeedsEntry(t.runtime.definition, required),
);
}
if (graphNeedsEntry(definition) && !options.entryPath) {
throw new Error("entryPath required for this sandboxed graph");
} Type guard
const needsSandboxEntry = (def: AgentDefinition): boolean =>
def.sandbox === "required" || def.tools.some(t =>
t.runtime?.kind === "subagent" && needsSandboxEntry(t.runtime.definition)); Prevention
- Treat entryPath as mandatory whenever sandbox: "required" appears anywhere in the graph
- Add a unit test that walks the definition graph for sandbox requirements
- Consider sandbox: "host" for interactive agents that need real host access
When it happens
Trigger: Calling prepareHarnessToolSandbox(definition, { rootDir }) with no entryPath while definition.sandbox === "required" (or any subagent in the tool graph inherits required sandbox and has non-subagent tools).
Common situations: Migrating a test harness from optional to required sandbox and forgetting the entryPath option; a subagent deep in the tool graph declaring sandbox: "required", which propagates the requirement up to the root bridge call.
Related errors
- cave_live_eval_sandbox_profile_missing
- cave_live_eval_sandbox_profile_invalid
- cave_harness_model_invalid
- caveman agent: unknown sandbox mode ${JSON.stringify(sandbox
- cave_sandbox_credential_capability_ambiguous
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/568d06b73fad38a5.
Report an issue: GitHub.