{"record":{"id":"a21f481a25c77ecd","repo":"astrid-runtime/astrid","slug":"corpus-input-changed-during-throughput-measurement","errorCode":null,"errorMessage":"corpus input changed during throughput measurement: expected {} bytes, read {observed_bytes}","messagePattern":"corpus input changed during throughput measurement: expected (.+?) bytes, read (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/astrid-storage-chunker-evidence/src/corpus.rs","lineNumber":297,"sourceCode":"                        input.logical_bytes(),\n                        candidate,\n                        hash_records,\n                        &mut guard,\n                    )?\n                },\n                Input::Memory(bytes) => measure_reader(\n                    Cursor::new(bytes.as_ref()),\n                    input.logical_bytes(),\n                    candidate,\n                    hash_records,\n                    &mut guard,\n                )?,\n            };\n            elapsed = elapsed\n                .checked_add(started.elapsed())\n                .ok_or_else(|| anyhow::anyhow!(\"corpus throughput duration overflow\"))?;\n            if observed_bytes != input.logical_bytes() {\n                bail!(\n                    \"corpus input changed during throughput measurement: expected {} bytes, read {observed_bytes}\",\n                    input.logical_bytes()\n                );\n            }\n            input.validate_current_file()?;\n        }\n        black_box(guard);\n        Ok(elapsed)\n    }\n\n    fn logical_bytes(&self) -> Result<u64> {\n        self.inputs.iter().try_fold(0_u64, |total, input| {\n            total\n                .checked_add(input.logical_bytes())\n                .ok_or_else(|| anyhow::anyhow!(\"corpus logical byte count overflow\"))\n        })\n    }\n","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-chunker-evidence/src/corpus.rs#L279-L315","documentation":"During throughput measurement, the corpus input is read repeatedly and each pass checks that the number of bytes read matches the input's declared `logical_bytes()`. A mismatch means the underlying file (or in-memory buffer) changed while being benchmarked, so the measurement is invalid and the crate bails.","triggerScenarios":"`measure_throughput` (called from `measure_throughput_samples`) reads a corpus input and `observed_bytes != input.logical_bytes()` — the source data was appended to, truncated, or rewritten during the timed loop.","commonSituations":"Another process (editor, build step, log rotation, sync tool) modifying the corpus file mid-benchmark; the caller mutating shared in-memory inputs between samples; running benchmarks against a live/logged file path.","solutions":["Identify and stop whatever is modifying the corpus file during the benchmark (editors, log writers, sync daemons).","Copy the corpus to a stable, private location before measuring and benchmark the copy.","Use fixed in-memory corpora instead of live files for throughput tests.","Re-run the measurement after ensuring the file is static; `input.validate_current_file()` results can help pinpoint the change."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Ensure the corpus file is stable before benchmarking\nlet before = std::fs::metadata(&path)?.len();\nstd::thread::sleep(std::time::Duration::from_millis(100));\nassert_eq!(std::fs::metadata(&path)?.len(), before, \"file is being modified; use a snapshot copy\");","typeGuard":null,"tryCatchPattern":"match measure_throughput(&mut input, /* ... */) {\n    Err(e) if e.to_string().contains(\"changed during throughput measurement\") => {\n        log::warn!(\"input mutated mid-benchmark; re-running on a frozen copy\");\n        // copy input to a temp snapshot and retry\n    }\n    other => other,\n}","preventionTips":["Benchmark against snapshot copies, never live/logged files","Stop editors, sync daemons, and log rotation on corpus directories during runs","Prefer in-memory corpora for throughput measurement","Don't share mutable corpus inputs across concurrent benchmark tasks"],"tags":["benchmark","concurrency","file-changed","throughput"],"backgroundTag":"file-changed-during-read","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}