JuliusBrussee/caveman · error · Error

cave_harness_request_invalid

cave_harness_request_invalid

Error message

cave_harness_request_invalid

What it means

The caveman-shrink CLI reads stdin through readBoundedInput, which uses io.LimitReader with maxStdinBytes+1 (32 MiB) and errors with code cave_input_too_large when the input exceeds that bound. The limit exists to prevent unbounded memory use when shrinking large documents. The error carries a stable code prefix so callers can match on cave_input_too_large.

Source

Thrown at packages/agent/src/adapters.ts:127

  return Object.freeze({
    id,
    version: identity.adapterVersion,
    manifest,
    contractSHA256,
    async run(request: HarnessRequest): Promise<HarnessResult> {
      const frozenRequest = snapshotRequest(request);
      const prepared = prepareLockedHarnessExecution({
        build: frozenRequest.build,
        harness: id,
        adapterVersion: identity.adapterVersion,
        upstreamVersion: identity.upstreamVersion,
        contextIR: frozenRequest.contextIR,
        plan: frozenRequest.plan,
      });
      const { build, planSHA256, contextIRSHA256 } = prepared;
      if (typeof frozenRequest.prompt !== "string" || frozenRequest.prompt.length === 0 ||
          typeof frozenRequest.runID !== "string" || frozenRequest.runID.length === 0) {
        throw new Error("cave_harness_request_invalid");
      }
      if (isAborted(frozenRequest.signal)) throw new Error("cave_harness_aborted");
      validateTransformEvidence(frozenRequest, frozenRequest.plan);
      const execution = snapshotExecution(await invoke(frozenRequest));
      if (isAborted(frozenRequest.signal)) throw new Error("cave_harness_aborted");
      validateExecution(execution, frozenRequest.plan);
      return {
        terminal: execution.terminal,
        text: execution.text,
        provider: execution.provider,
        model: execution.model,
        inputTokens: execution.inputTokens,
        outputTokens: execution.outputTokens,
        cacheReadTokens: execution.cacheReadTokens,
        cacheWriteTokens: execution.cacheWriteTokens,
        reasoningTokens: execution.reasoningTokens,
        totalTokens: execution.totalTokens,
        costUsd: execution.costUsd,

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Split the input into chunks under 32 MiB and shrink each chunk separately.
  2. Pre-filter the document to only the sections you need (e.g. extract the tools array first) before piping.
  3. If you control the build, raise maxStdinBytes in shrink/cmd/caveman-shrink/main.go:23 — but verify available memory first.

Example fix

# before
cat huge-dump.json | caveman-shrink

# after
jq '{tools: .tools}' huge-dump.json | caveman-shrink
# or split: split -b 16m huge-dump.json chunk. && for f in chunk.*; do caveman-shrink < "$f"; done
Defensive patterns

Strategy: validation

Validate before calling

# shell: check size before piping
f=huge.json
max=$((32 * 1024 * 1024))
size=$(stat -c%s "$f")
if [ "$size" -gt "$max" ]; then
  echo "input $size exceeds $max bytes; splitting or filtering required" >&2
  jq '{tools: .tools}' "$f" | caveman-shrink
else
  caveman-shrink < "$f"
fi

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "cave_input_too_large") {
        // split input into <32 MiB chunks and retry each chunk separately
    }
}

Prevention

When it happens

Trigger: Piping a file or stream larger than 32 MiB into `caveman-shrink` on stdin (e.g. cat huge.json | caveman-shrink), since main.go:47 calls readBoundedInput(os.Stdin, maxStdinBytes) with maxStdinBytes = 32 << 20.

Common situations: Feeding a huge tool catalog, log dump, or model output to the shrinker; concatenating many documents into one stdin stream; a generating process looping and appending output until it crosses 32 MiB.

Related errors


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