JuliusBrussee/caveman · error
cave_sandbox_input_limit
cave_sandbox_input_limit
Error message
cave_sandbox_input_limit
What it means
The sandbox tool worker reads its request frame from stdin and enforces a hard 1,048,576-byte (1 MiB) limit; exceeding it throws cave_sandbox_input_limit before any parsing. The cap bounds worker memory and keeps the length-prefixed protocol cheap — oversized tool params are rejected up front rather than buffered.
Source
Thrown at packages/agent/src/tool-worker.ts:81
process.exit(1);
});
async function readRequest(): Promise<{
entry: string;
agentPath: string[];
rootDefinitionSha256: string;
toolDefinitionSha256: string;
tool: string;
params: unknown;
allowSideEffects: boolean;
allowNetwork: boolean;
}> {
const chunks: Buffer[] = [];
let size = 0;
for await (const chunk of stdin) {
const buffer = Buffer.from(chunk);
size += buffer.byteLength;
if (size > 1_048_576) throw new Error("cave_sandbox_input_limit");
chunks.push(buffer);
}
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
}
try {
const request = await readRequest();
if (typeof request.entry !== "string" || !Array.isArray(request.agentPath) ||
request.agentPath.length > 8 ||
request.agentPath.some((item) => typeof item !== "string" ||
!/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(item)) ||
typeof request.rootDefinitionSha256 !== "string" ||
!/^[a-f0-9]{64}$/.test(request.rootDefinitionSha256) ||
typeof request.toolDefinitionSha256 !== "string" ||
!/^[a-f0-9]{64}$/.test(request.toolDefinitionSha256) ||
typeof request.tool !== "string" ||
!/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(request.tool) ||
typeof request.allowSideEffects !== "boolean" ||View on GitHub (pinned to 27d5a3981a)
Solutions
- Pass a file path (or digest/reference) instead of inline content, and let the sandboxed tool read the file itself.
- Trim or chunk params so the JSON-serialized frame stays well under 1 MiB.
- Move large payloads into the entry/definition bundle rather than the per-invocation request.
Example fix
// before
const out = await tool({ data: hugeBase64String }); // > 1 MiB frame
// after
await fs.writeFile(tmp, hugeBase64String);
const out = await tool({ dataPath: tmp }); Defensive patterns
Strategy: validation
Validate before calling
const INPUT_LIMIT = 1_048_576;
function withinSandboxInputLimit(request: unknown): boolean {
const size = Buffer.byteLength(JSON.stringify(request) ?? "", "utf8");
return size <= INPUT_LIMIT;
}
if (!withinSandboxInputLimit(frame)) throw new Error("params too large for sandbox worker"); Try / catch
try {
await invokeSandboxedTool(frame);
} catch (error) {
if (error instanceof Error && error.message === "cave_sandbox_input_limit") {
// do not retry the same payload: pass a file reference instead of inline data
} else throw error;
} Prevention
- Keep serialized tool params well under 1 MiB — the limit counts the whole request frame.
- Pass file paths/digests for large data; read contents inside the sandbox.
- Measure Buffer.byteLength(JSON.stringify(params)) when in doubt.
When it happens
Trigger: A sandboxed tool invocation whose serialized request frame (entry, agentPath, digests, tool name, and especially params) exceeds 1 MiB — e.g. passing a huge document, base64 blob, or large array as tool arguments.
Common situations: Feeding whole files or logs into a sandboxed tool's params instead of reading them inside the sandbox; pasting large inline data because the tool has no file-path parameter.
Related errors
- cave_harness_upstream_version_invalid
- cave_harness_artifact_digest_invalid
- cave_sandbox_failure_not_serializable
- cave_sandbox_request_invalid
- hook payload too large
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/d546126d385809cf.
Report an issue: GitHub.