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
- Split the input into chunks under 32 MiB and shrink each chunk separately.
- Pre-filter the document to only the sections you need (e.g. extract the tools array first) before piping.
- 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
- Measure input size with stat/wc -c before piping to the CLI.
- Pre-filter documents to the needed substructure (e.g. jq '{tools}') instead of sending entire dumps.
- Treat 32 MiB as a hard contract in pipeline scripts; add a size assertion in CI.
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
- hook payload too large
- cave_input_too_large
- option not found
- cave_harness_adapter_version_invalid
- cave_harness_upstream_version_invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/02c6433bd3ec28ed.
Report an issue: GitHub.