astrid-runtime/astrid · error

unknown Astrid volume operation

Error message

unknown Astrid volume operation

What it means

Volume operation opcodes are decoded from a single byte on the wire; only 1..=8 are defined (Truncate, Remove, Rename, Replace, MetadataTransaction, Commit, etc.). decode maps any other byte to InvalidData. This indicates a corrupted, truncated-shifted, or written-by-a-newer-version record stream.

Solutions

  1. Ensure the same or newer version of astrid-storage reads the volume — check for version skew between writer and reader.
  2. Verify the record offset passed to decode is the actual start of a record (opcode byte first), not mid-record.
  3. Run the volume recovery path (recover_container) to resynchronize to a valid commit header.
  4. Restore the volume from backup if the record stream is physically corrupted.
Defensive patterns

Strategy: try-catch

Try / catch

match VolumeOperation::decode(byte) {
    Ok(op) => apply(op),
    Err(e) if e.kind() == io::ErrorKind::InvalidData => {
        // log offset + bytes, run recovery, fail fast on version skew
        recover_container(file)?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Reading a volume record whose operation byte is 0 or >8 — e.g. a corrupted record, misaligned offset in the record stream, or a volume written by a newer library version with extra opcodes.

Common situations: Version skew: a volume file created by a newer astrid-storage release is opened by an older binary; disk corruption or a torn write landing in the opcode byte; decoding a byte stream at the wrong offset so a length field is read as the opcode.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at crates/astrid-storage/src/volume/hosted/mod.rs:455

    Remove = 4,
    Rename = 5,
    Replace = 6,
    MetadataTransaction = 7,
    Commit = 8,
}

impl Operation {
    fn decode(value: u8) -> io::Result<Self> {
        match value {
            1 => Ok(Self::Create),
            2 => Ok(Self::Write),
            3 => Ok(Self::Truncate),
            4 => Ok(Self::Remove),
            5 => Ok(Self::Rename),
            6 => Ok(Self::Replace),
            7 => Ok(Self::MetadataTransaction),
            8 => Ok(Self::Commit),
            _ => Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "unknown Astrid volume operation",
            )),
        }
    }
}

fn apply_metadata_mutations(
    regions: &mut BTreeMap<VolumeRegion, RegionState>,
    mutations: &[VolumeMetadataMutation],
) -> io::Result<()> {
    for mutation in mutations {
        match mutation {
            VolumeMetadataMutation::Rename {
                source,
                destination,
            } => {
                if regions.contains_key(destination) {

View on GitHub (pinned to affd8760f4)