astrid-runtime/astrid · error

invalid Astrid volume record length at

Error message

invalid Astrid volume record length at {offset}

What it means

A record header claims a total_len greater than the bytes remaining in the region, and no physically valid record follows it, so recovery cannot interpret the tail as another record. Because this is the final bad-length record (no valid successor found), recovery reports plain 'invalid record length' InvalidData for that offset.

Solutions

  1. Check whether the volume file is complete (size matches what the writer expected); restore or re-sync an incompletely copied/truncated file.
  2. Recover from backup or the last committed footer/commit point.
  3. If only the tail record is affected and the region tolerates losing the last write, discard the torn tail and re-open the volume.
  4. Investigate why the writer was interrupted (OOM, disk-full, kill -9) before reusing the volume.
Defensive patterns

Strategy: try-catch

Validate before calling

// cheap pre-check: ensure expected file size is present
let meta = file.metadata()?;
if meta.len() < expected_min_volume_size { return Err("volume file truncated"); }

Try / catch

match recover_from_headers(&file) {
    Err(e) if e.kind() == io::ErrorKind::InvalidData && e.to_string().contains("invalid Astrid volume record length") => {
        // treat as torn tail: recover to last good record or restore backup
    }
    other => other?,
}

Prevention

When it happens

Trigger: handle_bad_length (from read_header) finds total_len > remaining and has_physically_valid_record_after(offset+1) is false — the tail of the volume contains a header whose length cannot fit, with no resynchronizable record after it (e.g. torn final write).

Common situations: The process crashed mid-append leaving a partial record header at the tail; the volume file was truncated (copied incompletely, disk full during write); a caller recovers a file captured mid-write.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/b3606c3dfed94f91. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-storage/src/volume/hosted/recover.rs:423

fn handle_bad_length(
    file: &File,
    offset: u64,
    physical_len: u64,
    total_len: u64,
    remaining: u64,
) -> io::Result<Option<RecordHeader>> {
    if total_len > remaining
        && has_physically_valid_record_after(file, offset.saturating_add(1), physical_len)?
    {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!("invalid interior Astrid volume record length at {offset}"),
        ));
    }
    if total_len > remaining {
        return Ok(None);
    }
    Err(io::Error::new(
        io::ErrorKind::InvalidData,
        format!("invalid Astrid volume record length at {offset}"),
    ))
}

fn read_record_payload(file: &File, header: &RecordHeader) -> io::Result<Option<Vec<u8>>> {
    if header.operation == Operation::Write {
        return Ok(None);
    }
    let max_payload = if header.operation == Operation::Commit {
        MAX_COMMIT_SNAPSHOT_BYTES
    } else {
        MAX_METADATA_PAYLOAD_BYTES
    };
    if header.payload_len > max_payload {
        return Err(invalid_transition(
            "Astrid volume metadata payload exceeds the recovery bound",
        ));

View on GitHub (pinned to affd8760f4)