{"record":{"id":"9bc42bdcd64276f7","repo":"Hmbown/CodeWhale","slug":"late-usage-ledger-exceeds-its-size-bound-session-manager","errorCode":null,"errorMessage":"late usage ledger {} exceeds its size bound","messagePattern":"late usage ledger (.+?) exceeds its size bound","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/session_manager.rs","lineNumber":1494,"sourceCode":"            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"late usage ledger exceeds its size bound\",\n            ));\n        }\n        write_atomic(path, &bytes)\n    }\n\n    fn load_late_usage_unlocked(path: &Path) -> io::Result<LateUsageLedger> {\n        let file = match open_private_read_file(path) {\n            Ok(file) => file,\n            Err(error) if error.kind() == io::ErrorKind::NotFound => {\n                return Ok(LateUsageLedger::default());\n            }\n            Err(error) => return Err(error),\n        };\n        let metadata = file.metadata()?;\n        if metadata.len() > MAX_LATE_USAGE_LEDGER_BYTES {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\n                    \"late usage ledger {} exceeds its size bound\",\n                    path.display()\n                ),\n            ));\n        }\n        use std::io::Read as _;\n        let mut raw = Vec::with_capacity(\n            usize::try_from(metadata.len().min(MAX_LATE_USAGE_LEDGER_BYTES)).unwrap_or(0),\n        );\n        file.take(MAX_LATE_USAGE_LEDGER_BYTES.saturating_add(1))\n            .read_to_end(&mut raw)?;\n        if u64::try_from(raw.len()).unwrap_or(u64::MAX) > MAX_LATE_USAGE_LEDGER_BYTES {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\n                    \"late usage ledger {} exceeds its size bound\",","sourceCodeStart":1476,"sourceCodeEnd":1512,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/session_manager.rs#L1476-L1512","documentation":"When loading the late-usage ledger, read_late_usage_ledger first checks the file's metadata length against the 1 MiB cap (MAX_LATE_USAGE_LEDGER_BYTES) and rejects an oversized file with this InvalidData io::Error before reading any bytes. The message includes the offending path so the user can locate and fix the file. It is the pre-read guard; the read path has a second equivalent check (see error 2334). Thrown from crates/tui/src/session_manager.rs:1494.","triggerScenarios":"Opening the ledger file at a session directory path when fs metadata reports len > 1024*1024 — e.g. the file was written by an older build with no bound, appended to repeatedly, or the path points at the wrong/large file (misconfigured session directory).","commonSituations":"Upgrading Codewhale from a version that never bounded the ledger; a runaway bug that appended entries on every startup; pointing Codewhale's state directory at another large file; restoring a session directory backup that contains a bloated ledger.","solutions":["Delete the oversized ledger file (it is derivable state) so Codewhale starts with a default LateUsageLedger.","Truncate/prune the JSON by hand: keep the newest entries under 1 MiB, preserving the ledger's JSON structure.","Check whether an old Codewhale version or another process keeps appending to the file; stop that writer or upgrade it to the bounded version.","Verify the configured session/state directory points at Codewhale's own files, not an unrelated large file."],"exampleFix":"// before: ledger grown to 4 MiB by an old build, load refuses\nError: late usage ledger /home/me/.local/state/codewhale/late_usage.json exceeds its size bound\n// after\n$ rm /home/me/.local/state/codewhale/late_usage.json  # or trim to <1MiB, then restart Codewhale","handlingStrategy":"validation","validationCode":"let meta = std::fs::metadata(ledger_path)?;\nif meta.len() > 1024 * 1024 {\n    // oversized before the library opens it: delete or trim now\n    std::fs::remove_file(ledger_path)?;\n}","typeGuard":"fn ledger_file_within_bound(path: &Path) -> bool {\n    std::fs::metadata(path).map_or(true, |m| m.len() <= 1024 * 1024)\n}","tryCatchPattern":"match read_late_usage_ledger(path) {\n    Ok(ledger) => use(ledger),\n    Err(e) if e.to_string().contains(\"exceeds its size bound\") => {\n        let _ = std::fs::remove_file(path); // ledger is re-derivable; start fresh\n        use(LateUsageLedger::default());\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep exactly one Codewhale process per state directory so no unbounded writer appends to the ledger.","Upgrade from pre-bound legacy versions and trim/delete their oversized ledger once.","Point the session/state directory only at Codewhale's own files.","After restoring backups, check ledger file sizes before starting."],"tags":["io","size-limit","ledger","session-state"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}