{"record":{"id":"aaf2842a4b3a0efd","repo":"BigPizzaV3/CodexPlusPlus","slug":"file-grew-beyond-the-size-limit","errorCode":null,"errorMessage":"File grew beyond the size limit","messagePattern":"File grew beyond the size limit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/native_browser.rs","lineNumber":191,"sourceCode":"        options.share_mode(0x1).custom_flags(0x00200000);\n    }\n    let file = options.open(path)?;\n    let meta = file.metadata()?;\n    #[cfg(windows)]\n    {\n        use std::os::windows::fs::MetadataExt;\n        ensure!(\n            meta.file_attributes() & 0x400 == 0,\n            \"File is a reparse point\"\n        );\n    }\n    ensure!(\n        meta.is_file() && meta.len() <= limit,\n        \"Unexpected file type or size\"\n    );\n    let mut bytes = Vec::new();\n    file.take(limit + 1).read_to_end(&mut bytes)?;\n    ensure!(\n        bytes.len() as u64 <= limit,\n        \"File grew beyond the size limit\"\n    );\n    Ok(bytes)\n}\n\nfn write_new(path: &Path, bytes: &[u8]) -> Result<File> {\n    let _guards = pin_parents(path)?;\n    let mut file = OpenOptions::new().write(true).create_new(true).open(path)?;\n    file.write_all(bytes)?;\n    file.sync_all()?;\n    Ok(file)\n}\n\nfn atomic_write(path: &Path, bytes: &[u8]) -> Result<()> {\n    atomic_write_with_modified(path, bytes, None)\n}\n","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-core/src/native_browser.rs#L173-L209","documentation":"This is the race-closing check in read_regular: even though the metadata size was within the limit, the file is re-read with file.take(limit + 1), and the actual byte count is verified to be at most limit. It throws when the file was modified (grew) between the metadata query and the read — i.e. a concurrent writer changed the file during the read, so the previously validated size snapshot is stale.","triggerScenarios":"A concurrent process (Codex updater, the browser runtime itself, another library instance, antivirus quarantine/restore) appends to or rewrites the target file while read_regular is in progress, so the bytes read exceed the limit even though metadata said it fit.","commonSituations":"Running prepare/patching while the Codex CLI or its browser runtime is actively running and rewriting files; two instances of the manager operating on the same installation concurrently; an update job racing a status read.","solutions":["Close the running Codex/browser runtime processes, then retry the operation.","Ensure only one instance of the manager/library operates on the installation at a time (the library already holds parent pins, but concurrent writers defeat any read).","Retry the read — a transient race typically succeeds once the concurrent writer stops.","If the file is persistently larger than the limit now, restore the original file from a clean installation (see 'Unexpected file type or size')."],"exampleFix":"// before: patching while the runtime is live\nStart-Process codex; cargo run -- prepare\n// after: stop the runtime first, then patch\nStop-Process -Name codex -ErrorAction SilentlyContinue; cargo run -- prepare","handlingStrategy":"retry","validationCode":"fn size_within(path: &Path, limit: u64) -> bool {\n    std::fs::metadata(path).map(|m| m.is_file() && m.len() <= limit).unwrap_or(false)\n}\n// check immediately before the read, and again on retry:\n// assert!(size_within(path, 32 * 1024 * 1024));","typeGuard":"fn stable_size(path: &Path, limit: u64, checks: usize, gap: std::time::Duration) -> bool {\n    (0..checks).all(|_| {\n        let ok = size_within(path, limit);\n        std::thread::sleep(gap);\n        ok\n    })\n}","tryCatchPattern":"for attempt in 0..3 {\n    match read_operation() {\n        Err(e) if e.to_string().contains(\"grew beyond the size limit\") && attempt < 2 => {\n            eprintln!(\"Concurrent writer detected; retrying after pause\");\n            std::thread::sleep(std::time::Duration::from_millis(500));\n        }\n        Err(e) => return Err(e.into()),\n        Ok(v) => { use_value(v); break; }\n    }\n}","preventionTips":["Stop the Codex CLI / browser runtime processes before preparing or restoring files","Run only one instance of the manager against a given installation at a time","Schedule patching outside of update windows when an updater may be writing files","If reads keep racing, check for active writers with Resource Monitor / handle.exe on the file"],"tags":["filesystem","race-condition","file-size","concurrency"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}