astrid-runtime/astrid · error · std::io::Error::InvalidData
unadmitted entry in a fresh Astrid durable root
Error message
unadmitted entry in a fresh Astrid durable root: {} What it means
Thrown by validate_fresh_root_entries in crates/astrid-core/src/dirs.rs when initializing a brand-new Astrid durable root directory that contains a filesystem entry other than the expected 'astrid.volume' sentinel file. The library enforces that a fresh root is pristine: any extra file, subdirectory, or symlink means the root was not actually empty, so initialization aborts with InvalidData rather than silently adopting a dirty directory.
Solutions
- List the root directory and remove every entry except astrid.volume before re-running initialization.
- Point the Astrid root at a genuinely empty, dedicated directory instead of a shared folder.
- Exclude sync-client metadata (.DS_Store, desktop.ini, .nfs files) by disabling file-sync for the root or deleting those artifacts.
- If data from a prior install exists, restore/complete that install instead of treating the root as fresh.
Example fix
// before (root contaminated) $ ls $ASTRID_ROOT astrid.volume notes.txt error: unadmitted entry in a fresh Astrid durable root: notes.txt // after $ rm $ASTRID_ROOT/notes.txt $ ls $ASTRID_ROOT astrid.volume
Defensive patterns
Strategy: validation
Validate before calling
// Rust
fn root_is_fresh(root: &Path) -> io::Result<bool> {
for entry in std::fs::read_dir(root)? {
let entry = entry?;
if entry.file_name() != std::ffi::OsStr::new("astrid.volume") {
return Ok(false); // will trigger the error
}
}
Ok(true)
} Type guard
fn is_valid_volume_entry(entry: &std::fs::DirEntry) -> bool {
entry.file_name() == std::ffi::OsStr::new("astrid.volume")
} Try / catch
match ensure() {
Err(e) if e.kind() == io::ErrorKind::InvalidData
&& e.to_string().contains("unadmitted entry") => {
// inspect root, remove foreign entries, retry once
}
r => r?,
} Prevention
- Always point the durable root at a dedicated, empty directory
- Exclude the root from sync clients (Dropbox/OneDrive/iCloud)
- Check read_dir contents for non-astrid.volume entries before calling ensure()
- Never share the root path with other tools or scripts
When it happens
Trigger: Calling ensure() or validate_runtime_identity_provisioning() on a root directory that contains entries besides astrid.volume — e.g. a leftover file from a previous install, an OS artifact like .DS_Store or desktop.ini, a log file, or a user-created file inside the root before first initialization.
Common situations: Users pointing the durable root at a non-empty existing directory (Documents folder, home dir, mounted volume with stray files); CI containers writing temp files into the volume path; sync tools (Dropbox/OneDrive) placing metadata files inside the root before first run.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Astrid volume is not a regular file
- capsule projection contains a special file
- capsule projection path is not UTF-8
- capsule source is neither a directory nor a regular file
- executable replacement directories must exist
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/8ae737fe72614d46.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-core/src/dirs.rs:483
io::ErrorKind::InvalidData,
"stopped Astrid durable root cannot provision runtime identity sidecars",
));
}
Ok(())
}
fn validate_fresh_root_entries(&self) -> io::Result<UnsentinelledRootState> {
let mut entries = self.root().read_dir()?.collect::<Result<Vec<_>, _>>()?;
entries.sort_by_key(std::fs::DirEntry::file_name);
if entries.len() == 1 && entries[0].file_name() == std::ffi::OsStr::new("keys") {
self.validate_runtime_key_bootstrap(&entries[0].path())?;
return Ok(UnsentinelledRootState::RuntimeKeyBootstrap);
}
let mut state = UnsentinelledRootState::Empty;
for entry in entries {
let path = entry.path();
if entry.file_name() != std::ffi::OsStr::new("astrid.volume") {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"unadmitted entry in a fresh Astrid durable root: {}",
path.display()
),
));
}
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!(
"Astrid durable media is redirected or not a regular file: {}",
path.display()
),
));
}
crate::platform_fs::validate_private_file(&path)?;View on GitHub (pinned to affd8760f4)