JuliusBrussee/caveman · error

cave_sandbox_input_limit

cave_sandbox_input_limit

Error message

cave_sandbox_input_limit

What it means

The sandboxed tool worker reads its JSON request from stdin and enforces a hard 1 MiB (1_048_576 byte) input ceiling. If the parent sends a request larger than that, readRequest throws `cave_sandbox_input_limit`. This bounds worker memory and prevents oversized payloads from being silently buffered.

Solutions

  1. Reduce the tool arguments: pass a file path and let the tool read the data itself instead of embedding content in the request.
  2. Move large inline definition data into separate files so the agent graph sent to the worker stays under 1 MiB.
  3. Compress or truncate the payload before invocation (e.g. send a digest/handle, stream the data another way).
  4. If the payload is legitimately near the limit, restructure the tool to accept smaller incremental chunks across multiple calls.

Example fix

// before
await tools.search({ documents: hugeJsonString });

// after
await tools.search({ documentsPath: "./data/documents.json" });
Defensive patterns

Strategy: validation

Validate before calling

const MAX_WORKER_INPUT = 1_048_576;
const bytes = Buffer.byteLength(JSON.stringify(toolRequest), "utf8");
if (bytes > MAX_WORKER_INPUT) {
  throw new Error(`tool request ${bytes} bytes exceeds 1 MiB worker input limit; pass a file path instead`);
}

Try / catch

try {
  return await invokeSandboxedTool(tool, args);
} catch (err) {
  if (err instanceof Error && err.message.includes("cave_sandbox_input_limit")) {
    return invokeSandboxedTool(tool, await offloadLargeArgsToFiles(args));
  }
  throw err;
}

Prevention

When it happens

Trigger: A tool invocation whose request envelope (arguments, nested agent definitions, agentPath, entry metadata) exceeds 1 MiB when serialized to the worker over stdin.

Common situations: Passing very large blobs (embedded files, big JSON documents, base64 images) directly as tool arguments instead of via file paths; an agent definition graph bloated with inline data reaching the worker; a caller accidentally serializing entire datasets into tool arguments.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/d546126d385809cf. Report an issue: GitHub.

Appendix: 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 3ee70a1026)