astrid-runtime/astrid · critical
materialized file length differs from its descriptor
Error message
materialized file length differs from its descriptor
What it means
materialize rebuilds the file bytes from canonical chunk records and cross-checks the resulting Vec's length against the descriptor's logical_bytes. A mismatch means materialized content differs from the declared size, signaling data loss or corruption in the chunk records.
Solutions
- Rebuild the version from source so chunk records and logical_bytes are consistent.
- Verify each chunk record's canonical byte length matches its recorded length.
- Re-download/regenerate the evidence artifacts if they were produced elsewhere.
Defensive patterns
Strategy: try-catch
Validate before calling
let canonical: usize = chunks.iter().map(|c| record(c.id).canonical_len()).sum();
if canonical != logical_bytes as usize { return Err(anyhow!("canonical length drift")); } Try / catch
match version.materialize() {
Err(e) if e.to_string().contains("differs from its descriptor") => regenerate_evidence(),
other => other,
} Prevention
- Never re-encode or recompress canonical chunk records between build and materialize
- Validate record canonical lengths after loading persisted evidence
- Regenerate evidence artifacts rather than repairing them by hand
When it happens
Trigger: Calling materialize (used by delta_size) when the concatenated canonical chunk bytes total != self.logical_bytes — e.g. a chunk record's canonical bytes were re-encoded to a different length than originally counted.
Common situations: Chunk records transcoded or re-compressed between build and materialize; evidence files edited or truncated; mixing records from different measurement runs.
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
- ordered chunk traversal did not reconstruct the declared…
- a corpus produced no chunks
- a representation record must cover at least one logical…
- BLAKE3 evidence collision with inconsistent file lengths
- BLAKE3 evidence collision with inconsistent lengths
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/caf949d91fe80d3a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-storage-chunker-evidence/src/sketch.rs:451
}
fn record(&self, id: ObjectId) -> Result<&ObjectRecord> {
self.records
.binary_search_by_key(&id, |(object, _)| *object)
.ok()
.and_then(|index| self.records.get(index))
.map(|(_, record)| record)
.ok_or_else(|| anyhow::anyhow!("content DAG misses ordered chunk {id:?}"))
}
fn materialize(&self) -> Result<Vec<u8>> {
let capacity = usize::try_from(self.logical_bytes)?;
let mut bytes = Vec::with_capacity(capacity);
for chunk in &self.chunks {
bytes.extend_from_slice(self.record(chunk.id)?.canonical_bytes());
}
if bytes.len() != capacity {
bail!("materialized file length differs from its descriptor");
}
Ok(bytes)
}
}
fn collect_chunks(
id: ObjectId,
records: &BTreeMap<ObjectId, &ObjectRecord>,
offset: &mut u64,
chunks: &mut Vec<Chunk>,
) -> Result<()> {
let record = records
.get(&id)
.copied()
.ok_or_else(|| anyhow::anyhow!("content DAG misses {id:?}"))?;
match record.kind() {
ObjectKind::Chunk => {
let length = u64::try_from(record.canonical_bytes().len())?;View on GitHub (pinned to affd8760f4)