{"record":{"id":"206ac4afc8decbeb","repo":"Hmbown/CodeWhale","slug":"lane-exit-receipt-exceeds-bytes","errorCode":null,"errorMessage":"lane exit receipt {} exceeds {} bytes","messagePattern":"lane exit receipt (.+?) exceeds (.+?) bytes","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/lane/src/runtime.rs","lineNumber":524,"sourceCode":"        .map_err(|_| anyhow::anyhow!(\"lane proxy stderr logger panicked\"))?;\n    let mut exit_code = exit_status_code(status);\n    if let Some(error) = stdout_result.err().or_else(|| stderr_result.err()) {\n        append_proxy_failure(&log_path, &lane_id, &error)?;\n        exit_code = LANE_PROXY_FAILURE_EXIT_CODE;\n    }\n    write_lane_exit_receipt(&receipt_path, &receipt_tmp_path, &lane_id, exit_code)?;\n    Ok(exit_code)\n}\n\nfn read_lane_exit_receipt(log_path: &Path, lane_id: &str) -> Result<Option<LaneExitReceipt>> {\n    let path = lane_exit_receipt_path(log_path);\n    let metadata = match std::fs::metadata(&path) {\n        Ok(metadata) => metadata,\n        Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None),\n        Err(err) => return Err(err).with_context(|| format!(\"stat {}\", path.display())),\n    };\n    if metadata.len() > MAX_EXIT_RECEIPT_BYTES {\n        bail!(\n            \"lane exit receipt {} exceeds {} bytes\",\n            path.display(),\n            MAX_EXIT_RECEIPT_BYTES\n        );\n    }\n    let bytes = std::fs::read(&path).with_context(|| format!(\"read {}\", path.display()))?;\n    let receipt: LaneExitReceipt =\n        serde_json::from_slice(&bytes).with_context(|| format!(\"parse {}\", path.display()))?;\n    if receipt.lane_id != lane_id {\n        bail!(\n            \"lane exit receipt {} belongs to {}, expected {}\",\n            path.display(),\n            receipt.lane_id,\n            lane_id\n        );\n    }\n    Ok(Some(receipt))\n}","sourceCodeStart":506,"sourceCodeEnd":542,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/lane/src/runtime.rs#L506-L542","documentation":"read_lane_exit_receipt stats the receipt file and refuses to read it if it is larger than MAX_EXIT_RECEIPT_BYTES (4 KiB). The log proxy writes receipts far below this bound, so an oversized file signals corruption, truncation-garbage, or a foreign file sitting at lane_exit_receipt_path(log_path). The guard protects the reconciler from loading arbitrary data.","triggerScenarios":"Reconciling a lane (e.g. after a crash) where the receipt path under the lane's log directory holds a file > 4096 bytes — concatenated/truncated writes, a different tool's output, or a receipt from an incompatible format.","commonSituations":"A crashed writer leaving a partially-written receipt that was appended to across runs; log directories reused or shared between tools; disk corruption; the log proxy being replaced by a script that writes extra content to the same path.","solutions":["Inspect the file named in the message and delete it — a missing receipt is tolerated (read returns Ok(None)) and reconciliation falls back to tmux session state","Verify the log proxy binary is the runtime's own, not a wrapper adding output","Use a fresh log directory per lane generation to avoid inheriting foreign files"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"fn receipt_readable(path: &std::path::Path) -> bool {\n    std::fs::metadata(path)\n        .map(|m| m.len() <= 4 * 1024)\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match read_lane_exit_receipt(&log_path, &lane_id) {\n    Ok(receipt) => { /* use exit code */ }\n    Err(err) if err.to_string().contains(\"exceeds\") => {\n        // Oversized/corrupt receipt: remove it and reconcile via tmux state instead.\n        let _ = std::fs::remove_file(lane_exit_receipt_path(&log_path));\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Keep the lane log directory exclusive to the runtime and its log proxy","Do not wrap or replace the log proxy with tooling that appends extra output to the receipt path","Size-check the receipt during reconciliation cleanup routines"],"tags":["rust","lane","exit-receipt","size-limit","corruption"],"backgroundTag":"corrupt-state-file","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}