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

  1. List the root directory and remove every entry except astrid.volume before re-running initialization.
  2. Point the Astrid root at a genuinely empty, dedicated directory instead of a shared folder.
  3. Exclude sync-client metadata (.DS_Store, desktop.ini, .nfs files) by disabling file-sync for the root or deleting those artifacts.
  4. 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

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


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)