astrid-runtime/astrid · error

capsule projection contains a special file

Error message

capsule projection contains a special file: {}

What it means

This error means the projection inventory walk encountered a file that is neither a regular file nor a directory (e.g. a FIFO, device node, socket, or other special file). The kernel throws it because capsule projections must consist solely of ordinary files/directories; special files cannot be safely inventoried or projected and may hang reads or expose host devices.

Solutions

  1. Remove the special file shown in the error from the capsule directory and re-inventory
  2. Fix the build/run step that creates FIFOs/sockets in the capsule output (write them to a temp dir instead)
  3. Repackage the capsule from a clean build output containing only regular files
  4. Investigate any process still writing into the materialized capsule directory and stop it before activation

Example fix

# before: build leaves a socket in the output
my-server --socket build/capsule.sock

# after: keep runtime artifacts out of the capsule output
my-server --socket /tmp/app.sock
Defensive patterns

Strategy: validation

Validate before calling

let ft = std::fs::symlink_metadata(p)?.file_type();
if !(ft.is_file() || ft.is_dir()) {
    return Err(format!("special file in capsule output: {}", p.display()));
}

Try / catch

match result {
    Err(e) if e.to_string().contains("special file") => {
        // remove the FIFO/socket/device node and rebuild
    }
    other => other?,
}

Prevention

When it happens

Trigger: The recursive inventory walk (walk over the materialized capsule directory) hits a directory entry whose symlink_metadata file type is neither file nor dir — e.g. a named pipe or unix socket created inside the capsule directory by a build step or a process writing into the projection.

Common situations: A build tool creating FIFOs/sockets in the output directory before packaging; a dev server writing a .sock file into the capsule dir; packaging /dev-like trees; an archive that contained device nodes and was extracted with privileges.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

                    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() {
                    inventory.directories.insert(relative_text.to_owned());
                    walk(root, &path, inventory)?;
                } else if file_type.is_file() {
                    inventory.files.insert(relative_text.to_owned());
                } else {
                    anyhow::bail!(
                        "capsule projection contains a special file: {}",
                        path.display()
                    );
                }
            }
            Ok(())
        }

        let mut inventory = ProjectionInventory::default();
        walk(root, root, &mut inventory)?;
        Ok(inventory)
    }

    #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
    fn read_projection_file_nofollow(path: &Path) -> anyhow::Result<Vec<u8>> {
        use std::io::Read as _;

        let metadata = std::fs::symlink_metadata(path).map_err(|error| {

View on GitHub (pinned to affd8760f4)