{"record":{"id":"d4081d2fbab8bbba","repo":"astrid-runtime/astrid","slug":"invalid-astrid-volume-header","errorCode":null,"errorMessage":"invalid Astrid volume header","messagePattern":"invalid Astrid volume header","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage/src/volume/hosted/open.rs","lineNumber":111,"sourceCode":"                \"Astrid volume is not a regular file\",\n            ));\n        }\n        file.try_lock_exclusive().map_err(|error| {\n            if error.kind() == io::ErrorKind::WouldBlock {\n                io::Error::new(io::ErrorKind::WouldBlock, \"Astrid volume is already open\")\n            } else {\n                error\n            }\n        })?;\n        let length = file.metadata()?.len();\n        if length == 0 {\n            file.write_all(&VOLUME_MAGIC)?;\n            file.sync_all()?;\n        } else {\n            let mut magic = [0_u8; VOLUME_MAGIC.len()];\n            file.read_exact(&mut magic)?;\n            if magic != VOLUME_MAGIC {\n                return Err(io::Error::new(\n                    io::ErrorKind::InvalidData,\n                    \"invalid Astrid volume header\",\n                ));\n            }\n        }\n        let recovery = recover::recover_container(&mut file)?;\n        if file.metadata()?.len() != recovery.valid_len && !recovery.footer_present {\n            file.set_len(recovery.valid_len)?;\n            file.sync_all()?;\n        }\n        let footer_pending = !recovery.footer_present;\n        let mut state = ContainerState {\n            file,\n            sequence: recovery.sequence,\n            valid_len: recovery.valid_len,\n            durable_len: recovery.durable_len,\n            last_commit_offset: recovery.last_commit_offset,\n            last_commit_has_snapshot: recovery.last_commit_has_snapshot,","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage/src/volume/hosted/open.rs#L93-L129","documentation":"When opening an existing (non-empty) volume, the first VOLUME_MAGIC bytes are read and compared against the expected magic constant. A mismatch means the file was not created by this library or its header was overwritten/corrupted, so open aborts with InvalidData rather than parsing arbitrary data.","triggerScenarios":"Opening a file that exists but was not created as an Astrid volume (magic bytes absent); a header overwritten by other data; a truncated/garbage file that is non-empty; pointing the config at the wrong file.","commonSituations":"Typos in the configured volume path resolving to some other file; another tool writing to the same file; partial download/copy of a volume; attempting to open a plain text/binary file as a volume.","solutions":["Inspect the file's first bytes (`xxd <file> | head`) to confirm whether it is an Astrid volume.","Correct the configured path if you meant a different file.","If the file is not a volume, create a new one via the library's create path (empty length triggers VOLUME_MAGIC write).","Restore the volume from backup if the header was corrupted."],"exampleFix":"// before\nlet volume = HostedVolume::open(\"/data/not-a-volume.bin\")?;\n// after\nlet volume = HostedVolume::open(\"/data/volumes/volume.astrid\")?; // file starts with VOLUME_MAGIC","handlingStrategy":"validation","validationCode":"fn looks_like_astrid_volume(path: &Path) -> std::io::Result<bool> {\n    use std::io::Read;\n    let mut f = std::fs::File::open(path)?;\n    let mut magic = [0u8; 8]; // match VOLUME_MAGIC.len()\n    let n = f.read(&mut magic)?;\n    Ok(n == magic.len()) // compare against VOLUME_MAGIC in real usage\n}","typeGuard":null,"tryCatchPattern":"match HostedVolume::open(&path) {\n    Err(e) if e.kind() == io::ErrorKind::InvalidData\n        && e.to_string().contains(\"invalid Astrid volume header\") => {\n        eprintln!(\"{path:?} is not an Astrid volume; check path or recreate\");\n    }\n    other => { /* ... */ }\n}","preventionTips":["Create volumes only through the library so the magic header is written.","Verify the configured path resolves to the intended volume file.","Refuse to open files whose first bytes don't match the magic in tooling.","Keep volume files out of reach of other writers."],"tags":["storage","corruption","validation","header"],"backgroundTag":"checksum-mismatch","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"}