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
- Delete or move the special file named in the message out of the capsule source directory.
- Stop the process that created the socket/FIFO and clean the directory before archiving.
- 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
- Run dev servers with sockets outside the capsule dir
- Clean build/runtime artifacts before publishing
- Publish from fresh CI checkouts rather than shared workspaces
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
- legacy capsule contains special file
- capsule projection contains a special file
- capsule source symlink
- legacy capsule contains symlink
- an incomplete capsule authority update exists at
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)