astrid-runtime/astrid · error
Astrid volume path has no file name
Error message
Astrid volume path has no file name
What it means
OpenReclaimLock::for_path builds a registry key from the path's canonical parent directory plus its file-name component. If the path has no final component (e.g. it is "/", "..", or an empty/root path), file_name() returns None and the lock cannot be keyed, so InvalidInput is raised.
Solutions
- Pass the full path to the volume file, including its file name (e.g. /data/volumes/astrid.vol).
- Canonicalize or validate the configured path before opening and reject directory-only paths early.
- Check the config value/env var supplying the path for empty or root values.
Example fix
// before
let path = Path::new(&config.volume_dir); // directory, no file name
// after
let path = config.volume_dir.join("volume.astrid");
assert!(path.file_name().is_some()); Defensive patterns
Strategy: validation
Validate before calling
fn has_file_name(path: &Path) -> bool {
path.file_name().is_some()
} Try / catch
match HostedVolume::open(&path) {
Err(e) if e.to_string().contains("no file name") => {
eprintln!("configured volume path {path:?} lacks a file name component");
}
other => { /* ... */ }
} Prevention
- Validate that the configured path's file_name() is Some before opening.
- Store full file paths (not directories) in configuration for volume locations.
- Beware string operations (trimming, parent()) that strip the final component.
When it happens
Trigger: Passing a Path with no file name to the volume-open path — e.g. Path::new("/"), Path::new("."), Path::new(".."), or a path that is only a directory prefix ending in a separator with nothing after it.
Common situations: Config/env where the volume path variable is empty or set to a mount root; string manipulation that stripped the file name (e.g. trimming the last component); passing a directory instead of a volume file path.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Astrid volume is already open
- Astrid volume is not a regular file
- FUSE provider control path is not canonical
- live Astrid volume has no name
- live Astrid volume has no parent
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/7c0d83e3bbbbc932.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-storage/src/volume/hosted/open.rs:28
use parking_lot::{Mutex, MutexGuard};
use super::{ContainerState, HostedFileVolume, VOLUME_MAGIC, reclaim, recover};
type SharedOpenReclaimLock = Mutex<()>;
static OPEN_LOCKS: OnceLock<RwLock<BTreeMap<PathBuf, Weak<SharedOpenReclaimLock>>>> =
OnceLock::new();
/// Process-local serialization shared by open and physical reclaim for one
/// canonical parent plus final path component.
pub(super) struct OpenReclaimLock(Arc<SharedOpenReclaimLock>);
impl OpenReclaimLock {
fn for_path(path: &Path) -> io::Result<Self> {
let parent = path.parent().unwrap_or(Path::new("/"));
let canonical_parent = std::fs::canonicalize(parent)?;
let file_name = path.file_name().ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"Astrid volume path has no file name",
)
})?;
let key = canonical_parent.join(file_name);
let registry = OPEN_LOCKS.get_or_init(|| RwLock::new(BTreeMap::new()));
if let Some(lock) = registry
.read()
.expect("Astrid volume open-lock registry")
.get(&key)
.and_then(Weak::upgrade)
{
return Ok(Self(lock));
}
let mut guards = registry.write().expect("Astrid volume open-lock registry");
if let Some(lock) = guards.get(&key).and_then(Weak::upgrade) {
return Ok(Self(lock));
}View on GitHub (pinned to affd8760f4)