Hmbown/CodeWhale · error
Fleet artifact size changed while being read
Error message
Fleet artifact size changed while being read
What it means
After streaming the whole file, read_verified re-checks that both the bytes read and a fresh metadata().len() equal the size captured at open. If either disagrees, the file's size changed during the read (truncated, rewritten, or replaced) and the computed digest cannot represent a stable artifact, so verification fails.
Solutions
- Eliminate concurrent mutation: artifacts must be immutable after publish; stop any rewriter/truncator.
- Retry verification once the workspace is quiescent and confirm the receipt's size matches.
- Re-publish the artifact (new receipt) if the new content is legitimate, then verify against the new FleetArtifactRef.
- Restore the original bytes if the file was corrupted or truncated by an external job.
Defensive patterns
Strategy: retry
Try / catch
match read_verified(ws, &artifact, preview_limit) {
Err(e) if e.to_string().contains("size changed while being read") => {
eprintln!("artifact mutated during read; quiesce writers and retry");
}
other => other?,
} Prevention
- Disable cleanup/truncation jobs against the Fleet workspace during verification.
- Serialize publication and verification per artifact path.
- Re-publish and re-capture the receipt if content legitimately changed.
When it happens
Trigger: The artifact file is modified (shrunk via truncation/rewrite, or replaced via rename) between the initial metadata read and the post-read metadata check inside read_verified.
Common situations: A concurrent process rewriting the artifact in place; an external cleanup job truncating 'stale' files mid-verification; two readers/writers racing without the immutability contract being enforced.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Fleet artifact grew while being read
- Fleet artifact size changed
- Fleet artifact checksum does not match the recorded receipt
- An existing Fleet artifact contains different bytes
- conditional progress append does not accept terminal worker…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/81c0d9a368d680b5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/fleet/artifacts.rs:84
let mut hasher = Sha256::new();
let mut preview = Vec::new();
let mut buffer = [0_u8; 8192];
let mut total = 0_u64;
// The digest and returned preview consume exactly the same bytes from the
// same opened file. A changed/replaced pathname is never reopened for data.
let mut reader = (&file).take(size + 1);
loop {
let count = reader.read(&mut buffer)?;
if count == 0 {
break;
}
total += count as u64;
ensure!(total <= size, "Fleet artifact grew while being read");
hasher.update(&buffer[..count]);
let remaining = preview_limit.saturating_sub(preview.len() as u64) as usize;
preview.extend_from_slice(&buffer[..count.min(remaining)]);
}
ensure!(
total == size && file.metadata()?.len() == size,
"Fleet artifact size changed while being read"
);
ensure!(
format!("sha256:{}", crate::hashing::hex_bytes(hasher.finalize())) == checksum,
"Fleet artifact checksum does not match the recorded receipt"
);
Ok((preview, size))
}
#[cfg(test)]
mod tests {
use super::*;
use codewhale_protocol::fleet::FleetArtifactKind;
fn reference(path: &str, bytes: &[u8]) -> FleetArtifactRef {
FleetArtifactRef {
kind: FleetArtifactKind::Receipt,View on GitHub (pinned to 73e0f67d83)