JuliusBrussee/caveman · error · Error

caveman-code: no tool output recorded yet to prove recovery

Error message

caveman-code: no tool output recorded yet to prove recovery on

What it means

proveRecovery demonstrates reversibility of compression by round-tripping the largest recorded raw tool output. It reads session.agent.samples[0]; if the session has not recorded any tool output yet, there is nothing to prove recovery on and the call fails.

Source

Thrown at packages/agent/src/code.ts:957

  ];
}

// ---------------------------------------------------------------------------
// Recovery proof
// ---------------------------------------------------------------------------

export interface CodingRecoveryProof extends SegmentRecoveryProof {
  segment: string;
}

/**
 * Take the largest raw tool output this session produced, push it through the
 * same engine compress/retrieve pair the plan and `cave_retrieve` use, and
 * compare bytes. This is the reversibility proof, not a savings claim.
 */
export async function proveRecovery(session: CodingSession): Promise<CodingRecoveryProof> {
  const sample = session.agent.samples[0];
  if (!sample) throw new Error("caveman-code: no tool output recorded yet to prove recovery on");
  const proof = await proveSegmentRecovery({
    body: new TextEncoder().encode(sample.text),
    transformID: TOOL_RESULT_TRANSFORM,
    ...(session.options.engineBin === undefined ? {} : { engineBin: session.options.engineBin }),
  });
  return { ...proof, segment: sample.label };
}

export function formatRecoveryProof(proof: CodingRecoveryProof): string {
  if (proof.outcome === "recovered") {
    return `recovery proof: ${proof.segment} round-trip OK (sha256 match ${proof.originalSHA256.slice(0, 12)})`;
  }
  if (proof.outcome === "not_smaller") {
    return `recovery proof: ${proof.segment} not compressed — the engine kept the original bytes, nothing to recover`;
  }
  return `recovery proof: ${proof.segment} FAILED (sha256 mismatch) — the plan falls back to the original body`;
}

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Run at least one tool call (e.g. a grep or bash command) through the session before calling proveRecovery
  2. Guard the call: check `session.agent.samples.length > 0` (or an accessor like hasSamples) first
  3. In tests, seed the session with a recorded sample before asserting on the proof

Example fix

// before
const session = await createSession(opts);
const proof = await proveRecovery(session); // throws

// after
await session.tools.bash.execute({ command: "ls" }, signal);
if (session.agent.samples.length > 0) {
  const proof = await proveRecovery(session);
}
Defensive patterns

Strategy: type-guard

Validate before calling

const hasSamples = session.agent.samples.length > 0;
if (!hasSamples) {
  await session.tools.bash.execute({ command: "pwd" }, signal); // record one sample
}

Type guard

function canProveRecovery(session: CodingSession): boolean {
  return Array.isArray(session.agent.samples) && session.agent.samples.length > 0;
}

Prevention

When it happens

Trigger: Calling proveRecovery(session) immediately after creating a session, before any tool (bash/grep/edit_file/read/write) has executed and recorded a sample.

Common situations: Test harnesses constructing a session and asserting the recovery proof without first running a tool; CLI flows that print a proof unconditionally at startup.

Related errors


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