astrid-runtime/astrid · error · io::Error
live Astrid volume has no name
Error message
live Astrid volume has no name
What it means
verify_receipt_destination_is_live_path extracts the file-name component of the live Astrid volume path after checking its parent. If the path has no final file-name component (e.g. it ends in ".." or is a directory root), file_name() returns None and this InvalidInput error is raised. The name is needed to join with the canonicalized parent for the receipt comparison.
Source
Thrown at crates/astrid-core/src/dirs_layout_records.rs:205
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)
}
fn physical_path(destination: &LayoutTreeIdentityV1) -> io::Result<PathBuf> {
let bytes = hex::decode(&destination.physical_path_hex)
.map_err(|error| io::Error::other(format!("decode layout destination path: {error}")))?;
encoded_bytes_to_os_string(bytes).map(PathBuf::from)View on GitHub (pinned to affd8760f4)
Solutions
- Normalize the live path (strip trailing "."/"..") so it terminates in an actual file name.
- Use path.canonicalize() or clean the configured value before invoking retirement.
- Verify the config value points directly at the volume file, not its containing directory.
Example fix
// before
let live_path = Path::new("/var/lib/astrid/..");
// after
let live_path = std::fs::canonicalize("/var/lib/astrid")?.join("volume.bin"); Defensive patterns
Strategy: validation
Validate before calling
let live = Path::new(&volume_config);
if live.file_name().is_none() {
return Err("live volume path must end in a concrete file name");
} Try / catch
match retire_verified_legacy_source(...) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains("no name") => normalize_and_retry(),
other => other,
} Prevention
- Canonicalize configured paths before use to strip "."/".." segments.
- Reject configs with trailing path separators or relative components.
- Use std::fs::canonicalize on the live path before passing it in.
When it happens
Trigger: Called via retire_verified_legacy_source with a live_path such as "/some/dir/.." or "/" where Path::file_name() yields None, immediately after the parent check succeeds.
Common situations: A trailing ".." or "." left in a configured path; path normalization not performed before passing the live volume path; template-expanded config leaving a dangling path segment.
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 parent
- 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/c26d6023e973cfe5.
Report an issue: GitHub.