astrid-runtime/astrid · error · io::Error
live Astrid volume has no parent
Error message
live Astrid volume has no parent
What it means
verify_receipt_destination_is_live_path needs the parent directory of the live Astrid volume path to canonicalize and compare it against the receipt's recorded destination. If the live path has no parent component (i.e. it is a bare root path like "/" with no file-name portion for its parent lookup), this io::Error with InvalidInput is raised. This is essentially a degenerate-path guard.
Source
Thrown at crates/astrid-core/src/dirs_layout_records.rs:199
let metadata = std::fs::symlink_metadata(&path)?;
if metadata.file_type().is_symlink() || !metadata.is_file() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"layout migration destination is redirected or not a regular file: {}",
path.display()
),
));
}
crate::platform_fs::verify_no_redirects(&path)
}
pub(super) fn verify_receipt_destination_is_live_path(
destination: &LayoutTreeIdentityV1,
live_path: &Path,
) -> io::Result<()> {
let parent = live_path.parent().ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"live Astrid volume has no parent",
)
})?;
let file_name = live_path.file_name().ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"live Astrid volume has no name",
)
})?;
let canonical_parent = std::fs::canonicalize(parent)?;
if physical_path(destination)? != canonical_parent.join(file_name) {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"layout migration receipt destination path does not match the live Astrid volume",
));
}
verify_receipt_destination_authority(destination)View on GitHub (pinned to affd8760f4)
Solutions
- Fix the configured live volume path so it points at a file inside a directory, not the filesystem root.
- Check the config/env value that supplies the live path and ensure it includes a parent directory and file name.
- Log/print the live path before calling retire_verified_legacy_source to confirm it is non-root.
Example fix
// before
let live_path = Path::new("/");
// after
let live_path = Path::new("/var/lib/astrid/volume.bin"); Defensive patterns
Strategy: validation
Validate before calling
let live = Path::new(&volume_config);
if live.parent().is_none() || live == Path::new("/") {
return Err("live volume path must be a file inside a directory, not the root");
} Try / catch
match retire_verified_legacy_source(...) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains("no parent") => fix_volume_config(),
other => other,
} Prevention
- Validate configured volume paths point to files, never "/".
- Reject root paths at config-load time.
- Log the resolved live path before retirement.
When it happens
Trigger: verify_receipt_destination_is_live_path is called (via retire_verified_legacy_source) with live_path == "/" or another path whose Path::parent() returns None, so parent extraction fails before file_name extraction.
Common situations: Misconfigured volume path pointing at the filesystem root instead of a file inside a directory; an env var or config value like ASTRID_VOLUME="/" passed through unchanged; programmatic construction of the live path that dropped the file component.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- live Astrid volume has no name
- layout migration receipt destination path does not match the
- legacy state source is not a directory: {}
- {} is not a real directory: {}
- {} overlaps the Astrid durable root: {} overlaps {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/3c579314a3a1fb5e.
Report an issue: GitHub.