astrid-runtime/astrid · error

read capsule projection entry: {error}

Error message

read capsule projection entry: {error}

What it means

Thrown when a `read_dir` entry itself fails to be materialized into a `DirEntry` during the projection inventory walk. This happens when the underlying readdir call fails mid-iteration for a specific entry (e.g. the file was removed between listing and stat, or an IO error occurred on that slot).

Source

Thrown at crates/astrid-kernel/src/lib.rs:1627

        if components[2] != digest {
            anyhow::bail!("materialized capsule digest does not match durable registry");
        }
        Ok(())
    }

    /// Inventory a projection without traversing redirects or special files.
    #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
    fn inventory_projection_files(root: &Path) -> anyhow::Result<ProjectionInventory> {
        fn walk(
            root: &Path,
            directory: &Path,
            inventory: &mut ProjectionInventory,
        ) -> anyhow::Result<()> {
            for entry in std::fs::read_dir(directory).map_err(|error| {
                anyhow::anyhow!("read capsule projection {}: {error}", directory.display())
            })? {
                let entry = entry
                    .map_err(|error| anyhow::anyhow!("read capsule projection entry: {error}"))?;
                let path = entry.path();
                let relative = path.strip_prefix(root).map_err(|_| {
                    anyhow::anyhow!("capsule projection escaped its root: {}", path.display())
                })?;
                let relative_text = relative.to_str().ok_or_else(|| {
                    anyhow::anyhow!("capsule projection path is not UTF-8: {}", path.display())
                })?;
                let metadata = std::fs::symlink_metadata(&path).map_err(|error| {
                    anyhow::anyhow!("inspect capsule projection {}: {error}", path.display())
                })?;
                let file_type = metadata.file_type();
                if file_type.is_symlink() {
                    anyhow::bail!(
                        "capsule projection contains a symbolic link: {}",
                        path.display()
                    );
                }
                if file_type.is_dir() {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Retry the inventory walk; transient entry errors often resolve on a fresh pass.
  2. Ensure no concurrent process mutates the projection directory during inventory.
  3. If entry-level failures are acceptable, skip and log instead of failing the whole walk.
  4. Check filesystem health (dmesg / fsck) if errors persist.
Defensive patterns

Strategy: retry

Try / catch

match walk_inventory(root) {
    Err(e) if is_transient_entry_error(&e) => walk_inventory(root), // one retry
    other => other,
}

Prevention

When it happens

Trigger: Walking a projection directory while an entry is concurrently deleted/renamed, or the filesystem reports an IO error for a particular directory entry.

Common situations: Concurrent writers modifying the projection while an inventory is being built; network filesystems with flaky readdir; race between garbage collection and inventory.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/bd4dd5549405dcb5. Report an issue: GitHub.