{"record":{"id":"410d8ec784f6b73d","repo":"xai-org/grok-build","slug":"journal-exceeds-max-journal-bytes-bytes","errorCode":null,"errorMessage":"journal exceeds {MAX_JOURNAL_BYTES} bytes","messagePattern":"journal exceeds (.+?) bytes","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-workflow/src/journal.rs","lineNumber":264,"sourceCode":"            truncate_tail(path, new_len)?;\n        }\n        self.entries.pop();\n        self.bytes = new_len;\n        self.last_line_start = None;\n        Ok(true)\n    }\n}\n\nfn read_journal_bounded(path: &Path) -> std::io::Result<Vec<u8>> {\n    let metadata = std::fs::symlink_metadata(path)?;\n    if metadata.file_type().is_symlink() || !metadata.is_file() {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidData,\n            format!(\"journal is not a regular file: {}\", path.display()),\n        ));\n    }\n    if metadata.len() > MAX_JOURNAL_BYTES {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidData,\n            format!(\"journal exceeds {MAX_JOURNAL_BYTES} bytes\"),\n        ));\n    }\n    let mut options = std::fs::OpenOptions::new();\n    options.read(true);\n    #[cfg(unix)]\n    {\n        use std::os::unix::fs::OpenOptionsExt;\n        options.custom_flags(libc::O_NOFOLLOW);\n    }\n    let file = options.open(path)?;\n    let opened = file.metadata()?;\n    if !opened.is_file() || opened.len() > MAX_JOURNAL_BYTES {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidData,\n            \"journal changed during open\",\n        ));","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-workflow/src/journal.rs#L246-L282","documentation":"read_journal_bounded enforces a maximum journal size (MAX_JOURNAL_BYTES) before opening the file, rejecting oversized journals with io::ErrorKind::InvalidData. This bounds memory usage and load time when loading a journal, protecting against runaway or corrupt journals.","triggerScenarios":"Loading a journal whose file length exceeds MAX_JOURNAL_BYTES — typically after a very long-running workflow accumulated records, or a corrupted/appending-wrong-data journal grew unboundedly.","commonSituations":"Long-lived workflow processes appending for weeks without rotation/compaction; a bug causing repeated identical records; a foreign large file placed at the journal path.","solutions":["Rotate or truncate the journal: archive the old file and start fresh (the workflow will resume with an empty journal)","Compact/rewrite the journal keeping only the latest state per record","Increase MAX_JOURNAL_BYTES if the workload legitimately needs larger journals and memory permits"],"exampleFix":"# archive the oversized journal and let the library start a new one\nmv journal journal.old.1 && touch journal","handlingStrategy":"try-catch","validationCode":"fn journal_size_ok(path: &Path) -> std::io::Result<bool> {\n    Ok(std::fs::metadata(path)?.len() <= MAX_JOURNAL_BYTES)\n}\nif journal_size_ok(&journal_path).unwrap_or(true) {\n    load(&journal_path)?;\n} else {\n    std::fs::rename(&journal_path, journal_path.with_extension(\"old\"))?;\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = load(&journal_path) {\n    if e.kind() == std::io::ErrorKind::InvalidData {\n        // journal exceeds the size cap: archive it and start fresh\n        std::fs::rename(&journal_path, journal_path.with_extension(\"old\"))?;\n        load(&journal_path)?;\n    } else { return Err(e.into()); }\n}","preventionTips":["Rotate/compact journals periodically for long-running workflows","Monitor journal file size and alert before it approaches MAX_JOURNAL_BYTES","Investigate unbounded growth — it often indicates repeated/appended duplicate records"],"tags":["io","filesystem","limit","journal","rust"],"backgroundTag":"journal-size-exceeded","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}