astrid-runtime/astrid · error
Astrid volume is not a regular file
Error message
Astrid volume is not a regular file
What it means
After opening the volume file, open() stats it and requires metadata.is_file(). Paths that resolve to directories, FIFOs, devices, or reparse-point/symlink targets that are not regular files are rejected with InvalidData. This protects the locking and fixed-offset I/O model, which only works on regular files.
Source
Thrown at crates/astrid-storage/src/volume/hosted/open.rs:91
let swap_guard = open_lock.lock();
reclaim::recover_artifacts(&path)?;
let mut options = OpenOptions::new();
options.read(true).write(true).create(true);
#[cfg(unix)]
{
use std::os::unix::fs::OpenOptionsExt as _;
options.mode(0o600).custom_flags(libc::O_NOFOLLOW);
}
#[cfg(windows)]
{
use std::os::windows::fs::OpenOptionsExt as _;
use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_OPEN_REPARSE_POINT;
options.custom_flags(FILE_FLAG_OPEN_REPARSE_POINT);
}
let mut file = options.open(&path)?;
let metadata = file.metadata()?;
if !metadata.is_file() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Astrid volume is not a regular file",
));
}
file.try_lock_exclusive().map_err(|error| {
if error.kind() == io::ErrorKind::WouldBlock {
io::Error::new(io::ErrorKind::WouldBlock, "Astrid volume is already open")
} else {
error
}
})?;
let length = file.metadata()?.len();
if length == 0 {
file.write_all(&VOLUME_MAGIC)?;
file.sync_all()?;
} else {
let mut magic = [0_u8; VOLUME_MAGIC.len()];
file.read_exact(&mut magic)?;View on GitHub (pinned to affd8760f4)
Solutions
- Verify the path points at a regular file: run `file <path>` or check it is not a directory/symlink.
- Fix the configured volume path to reference the actual volume file.
- If a symlink is intentional, point the config at the real regular-file target.
- Recreate the volume with the library's create path if the file was replaced by something else.
Example fix
// before
let volume = HostedVolume::open("/data/volumes")?; // a directory
// after
let volume = HostedVolume::open("/data/volumes/volume.astrid")?; Defensive patterns
Strategy: validation
Validate before calling
fn is_regular_file(path: &Path) -> std::io::Result<bool> {
Ok(std::fs::metadata(path)?.is_file())
} Try / catch
match HostedVolume::open(&path) {
Err(e) if e.kind() == io::ErrorKind::InvalidData
&& e.to_string().contains("not a regular file") => {
eprintln!("{path:?} is not a regular file; fix VOLUME_PATH");
}
other => { /* ... */ }
} Prevention
- Check the target with fs::metadata(path).is_file() before opening.
- Do not point volume config at directories, pipes, or device nodes.
- Resolve symlinks intentionally and verify the target is a regular file.
When it happens
Trigger: Opening a volume path that is a directory; opening a special file (fifo/socket/device); opening through a symlink or Windows reparse point that resolves to a non-regular target (note FILE_FLAG_OPEN_REPARSE_POINT is used on Windows).
Common situations: Misconfiguration pointing VOLUME_PATH at a directory or a mount point; a broken provisioning step replaced the volume file with a symlink to something else; tmpfs/pipe-based test fixtures.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- capsule source is neither a directory nor a regular file: {}
- FUSE provider control path is not canonical
- mountpoint is not a directory: {}
- InvalidInput
- durable capsule {id} metadata names a hash for a non-WASM co
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/5ba0a9fd03ed07fe.
Report an issue: GitHub.