JuliusBrussee/caveman · error · Error
caveman agent: unknown sandbox mode ${JSON.stringify(sandbox
Error message
caveman agent: unknown sandbox mode ${JSON.stringify(sandbox)} What it means
Thrown by the agent() builder (packages/agent/src/index.ts:107): the sandbox option is not one of the framework's sandbox modes (SANDBOX_MODES — 'required', 'host', and the contained default set). Sandbox defaults to 'required'; any other string is rejected.
Source
Thrown at packages/agent/src/index.ts:107
instructions: string | FileSource;
model: Auto | string | Model<Api>;
reasoning?: AgentDefinition["reasoning"];
tools?: ToolDefinition[];
contexts?: ContextDefinition[];
memory?: MemoryDefinition;
output?: OutputDefinition;
sandbox?: AgentDefinition["sandbox"];
}): AgentDefinition {
if (!/^[a-z0-9][a-z0-9_-]{0,95}$/.test(options.id)) {
throw new Error(`caveman agent: invalid agent id ${JSON.stringify(options.id)}`);
}
const tools = Object.freeze([...(options.tools ?? [])]);
if (new Set(tools.map((item) => item.name)).size !== tools.length) {
throw new Error("caveman agent: duplicate tool name");
}
const sandbox = options.sandbox ?? "required";
if (!SANDBOX_MODES.includes(sandbox)) {
throw new Error(`caveman agent: unknown sandbox mode ${JSON.stringify(sandbox)}`);
}
const reserved = tools.find((item) => item.name.startsWith("cave_"));
if (reserved) {
throw new Error(
`caveman agent: tool prefix cave_ is reserved by framework (${reserved.name})`,
);
}
const definition: AgentDefinition = {
kind: "agent",
id: options.id,
instructions: options.instructions,
model: options.model,
reasoning: options.reasoning ?? "low",
tools,
contexts: Object.freeze([...(options.contexts ?? [])]),
sandbox,
...(options.memory === undefined ? {} : { memory: options.memory }),
...(options.output === undefined ? {} : { output: options.output }),View on GitHub (pinned to 27d5a3981a)
Solutions
- Use one of the documented SANDBOX_MODES values — 'required' (default containment), 'host' (explicit opt-in for tools needing real host access), or the other exported mode.
- Omit sandbox entirely if you want the default ('required').
- Type the option as AgentDefinition['sandbox'] so the compiler catches invalid literals before runtime.
Example fix
// before
agent({ sandbox: "none" as any, /* ... */ });
// after
agent({ sandbox: "host", /* ... */ }); // or omit sandbox for the 'required' default Defensive patterns
Strategy: type-guard
Validate before calling
const SANDBOX_MODES = ["required", "host"] as const; // keep in sync with the framework export
function isSandboxMode(v: unknown): v is (typeof SANDBOX_MODES)[number] {
return typeof v === "string" && (SANDBOX_MODES as readonly string[]).includes(v);
}
const sandbox = rawConfig.sandbox ?? "required";
if (!isSandboxMode(sandbox)) throw new Error(`unknown sandbox mode ${String(rawConfig.sandbox)}`); Type guard
function isSandboxMode(v: unknown): v is AgentDefinition["sandbox"] {
return typeof v === "string" && /^[a-z]+$/.test(v) && ["required", "host"].includes(v);
} Prevention
- Type the option as AgentDefinition['sandbox'] so invalid literals fail to compile.
- Validate sandbox values parsed from YAML/JSON config before calling agent().
- Remember 'host' is an explicit opt-in; there is no 'none'/'off' mode.
When it happens
Trigger: Calling agent({ sandbox: ... }) with a typo or unknown value such as 'optional', 'none', 'unsafe', 'docker', or passing the wrong type (number/boolean).
Common situations: Assuming a 'none'/'off' mode exists and passing it; typos like 'host' or 'RequireD'; copying config between framework versions where mode names changed; intending host mode for an interactive coding agent but misspelling 'host'.
Related errors
- cave_breaker_threshold_invalid
- cave_breaker_retry_backoff_invalid
- cave_live_eval_sandbox_profile_missing
- cave_live_eval_sandbox_profile_invalid
- caveman agent: subagent maxInputChars must be a positive int
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/ed1cd4fd368db2bf.
Report an issue: GitHub.