Hmbown/CodeWhale · error

lane exit receipt exceeds bytes

Error message

lane exit receipt {} exceeds {} bytes

What it means

read_lane_exit_receipt stats the receipt file (returning Ok(None) cleanly if absent) and rejects files larger than MAX_EXIT_RECEIPT_BYTES before reading. An oversized receipt is treated as corrupt/tampered state rather than a valid exit record.

Solutions

  1. Delete the oversized receipt file and let reconcile re-derive lane state (or rerun the lane to write a fresh receipt).
  2. Verify nothing external writes into the lane's runtime directory.
  3. If a legitimate new writer emits larger receipts, update MAX_EXIT_RECEIPT_BYTES consistently on both sides.
Defensive patterns

Strategy: try-catch

Validate before calling

if let Ok(m) = std::fs::metadata(&receipt_path) { if m.len() > MAX_EXIT_RECEIPT_BYTES { std::fs::remove_file(&receipt_path).ok(); } }

Try / catch

match read_lane_exit_receipt(&path, &lane_id) { Ok(None) => {/* no receipt yet */}, Ok(Some(r)) => {/* use r */}, Err(e) if e.to_string().contains("exceeds") => { fs::remove_file(&path).ok(); reconcile_fresh()?; } Err(e) => return Err(e) }

Prevention

When it happens

Trigger: reconcile() or the log-proxy test path reading an exit receipt file whose on-disk size exceeds MAX_EXIT_RECEIPT_BYTES.

Common situations: Corrupted or externally modified receipt files; leftovers from a writer version that allowed larger payloads; disk issues producing garbage files.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/206ac4afc8decbeb. Report an issue: GitHub.

Appendix: source

Thrown at crates/lane/src/runtime.rs:524

        .map_err(|_| anyhow::anyhow!("lane proxy stderr logger panicked"))?;
    let mut exit_code = exit_status_code(status);
    if let Some(error) = stdout_result.err().or_else(|| stderr_result.err()) {
        append_proxy_failure(&log_path, &lane_id, &error)?;
        exit_code = LANE_PROXY_FAILURE_EXIT_CODE;
    }
    write_lane_exit_receipt(&receipt_path, &receipt_tmp_path, &lane_id, exit_code)?;
    Ok(exit_code)
}

fn read_lane_exit_receipt(log_path: &Path, lane_id: &str) -> Result<Option<LaneExitReceipt>> {
    let path = lane_exit_receipt_path(log_path);
    let metadata = match std::fs::metadata(&path) {
        Ok(metadata) => metadata,
        Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None),
        Err(err) => return Err(err).with_context(|| format!("stat {}", path.display())),
    };
    if metadata.len() > MAX_EXIT_RECEIPT_BYTES {
        bail!(
            "lane exit receipt {} exceeds {} bytes",
            path.display(),
            MAX_EXIT_RECEIPT_BYTES
        );
    }
    let bytes = std::fs::read(&path).with_context(|| format!("read {}", path.display()))?;
    let receipt: LaneExitReceipt =
        serde_json::from_slice(&bytes).with_context(|| format!("parse {}", path.display()))?;
    if receipt.lane_id != lane_id {
        bail!(
            "lane exit receipt {} belongs to {}, expected {}",
            path.display(),
            receipt.lane_id,
            lane_id
        );
    }
    Ok(Some(receipt))
}

View on GitHub (pinned to 73e0f67d83)