astrid-runtime/astrid · error

capsule source contains unsupported special file

Error message

capsule source contains unsupported special file {}

What it means

Raised by collect_entries when a capsule source entry is neither a regular file, directory, nor an accepted symlink — i.e. an unsupported special file (FIFO, socket, device node). The library skips known metadata files but rejects any other non-regular entry to keep archives deterministic and portable.

Solutions

  1. Delete or move the special file named in the message out of the capsule source directory.
  2. Stop the process that created the socket/FIFO and clean the directory before archiving.
  3. Archive from a clean checkout/build output containing only regular files and directories.

Example fix

# before: dev-server socket inside capsule root
my-capsule/dev.sock

# after
rm my-capsule/dev.sock
Defensive patterns

Strategy: validation

Validate before calling

fn only_regular_entries(dir: &Path) -> std::io::Result<bool> {
    Ok(!walkdir(dir).any(|e| !e.file_type().is_file() && !e.file_type().is_dir()))
}

Type guard

fn is_archive_safe(md: &std::fs::FileType) -> bool {
    md.is_file() || md.is_dir()
}

Try / catch

match publish(...) {
    Err(e) if e.to_string().contains("unsupported special file") => { remove_special_files(&dir)?; retry(); }
    other => other?,
}

Prevention

When it happens

Trigger: Building a canonical archive from a source directory containing a FIFO/socket/device file at any depth; the entry is not named meta.json, authority.json, .env, or .env.json and is not a dir/file/symlink.

Common situations: Runtime artifacts (sockets from a dev server, pipes from build tooling) left inside the capsule directory; odd entries produced by container mounts or FUSE filesystems; a bad restore that created device nodes.

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/76b63183c46f9f1b. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-capsule-install/src/storage.rs:829

                || relative.file_name().and_then(|name| name.to_str()) == Some("target")
            {
                continue;
            }
            // Directory entries are included so empty directories survive
            // archive round-trips; their descendants are sorted recursively.
            entries.push((relative.clone(), metadata));
            collect_entries(root, &name, entries)?;
        } else if file_type.is_file() {
            let name = relative.file_name().and_then(|name| name.to_str());
            if matches!(
                name,
                Some("meta.json" | "authority.json" | ".env" | ".env.json")
            ) {
                continue;
            }
            entries.push((relative, metadata));
        } else {
            bail!(
                "capsule source contains unsupported special file {}",
                relative.display()
            );
        }
    }
    Ok(())
}

fn read_dir_sorted(path: &Path) -> anyhow::Result<Vec<(PathBuf, Metadata)>> {
    let mut children = Vec::new();
    let entries: ReadDir = fs::read_dir(path)
        .with_context(|| format!("read capsule source directory {}", path.display()))?;
    for entry in entries {
        let entry = entry.with_context(|| format!("read child of {}", path.display()))?;
        let name = entry.path();
        let metadata = fs::symlink_metadata(&name)
            .with_context(|| format!("inspect capsule source entry {}", name.display()))?;
        children.push((name, metadata));

View on GitHub (pinned to affd8760f4)