astrid-runtime/astrid · error
legacy source contains a special entry: {}
Error message
legacy source contains a special entry: {} What it means
snapshot_path_with_access can only fingerprint regular files and directories. If the top-level legacy source is neither (fifo, socket, device node, other special file), it cannot be hashed or counted as source entries, so the library raises InvalidData. Note validate_source_entry has already run for the path itself, so this fires when the top-level entry type is admissible to earlier checks but not a file/dir for snapshotting.
Source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:642
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("legacy source is an active mount: {}", path.display()),
));
}
let device = device_id(&metadata);
let mut hasher = blake3::Hasher::new_derive_key("astrid layout component source v1");
let mut identity = SourceInventory::default();
if metadata.is_file() {
// A top-level regular file is itself one source entry. Directory
// snapshots count children in `snapshot_dir`; keeping the same
// cardinality here lets retirement bind a single-file source to the
// exact preflight manifest as well.
identity.entries = SourceCount::new(1);
read_regular_file(path, &mut hasher, &mut identity)?;
} else if metadata.is_dir() {
snapshot_dir(path, path, device, access, &mut hasher, &mut identity)?;
} else {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("legacy source contains a special entry: {}", path.display()),
));
}
SourceIdentity::present(
SourceDigest::from_blake3(hasher.finalize()),
identity.entries,
identity.bytes,
)
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))
}
/// Validate one regular-file source using the same no-follow, private,
/// same-device, and mount checks as recursive snapshots. Distro lock files
/// keep their component-owned digest format, so they use this structural
/// check instead of the generic tree hash.
pub(super) fn validate_source_path(path: &Path) -> io::Result<()> {
let metadata = fs::symlink_metadata(path)?;View on GitHub (pinned to affd8760f4)
Solutions
- Stop the process owning the special file and remove it from the legacy source path.
- Restore the expected regular file or directory at that path (from backup or by re-creating the legacy layout).
- Re-run the migration/snapshot once the source is a plain file or directory.
Example fix
// before prw-r--r-- legacy-ctl (fifo) at the component source path // after rm legacy-ctl # restore or create a regular file/directory at the path, then re-run
Defensive patterns
Strategy: validation
Validate before calling
match std::fs::symlink_metadata(&source) {
Ok(m) if m.is_file() || m.is_dir() => {},
Ok(_) => eprintln!("{} is a special file; remove it first", source.display()),
Err(_) => {},
} Type guard
fn is_snapshotable(p: &Path) -> bool {
std::fs::symlink_metadata(p).map(|m| m.is_file() || m.is_dir()).unwrap_or(false)
} Try / catch
if let Err(e) = snapshot_path(&source) {
if e.to_string().contains("special entry") {
// remove/replace the special file at the source path, then retry
}
} Prevention
- Ensure legacy source paths hold only regular files/directories.
- Stop daemons that create sockets/pipes inside legacy component paths.
- Verify entry types with symlink_metadata before snapshotting.
When it happens
Trigger: Calling snapshot_path or snapshot_owner_controlled_path on a legacy source path that resolves to a special file rather than a regular file or directory; the final else-branch of the file/dir dispatch.
Common situations: A legacy component path occupied by a socket or pipe left by an old daemon; a device node appearing where data used to live; corrupted layout after a crashed tool.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- layout migration source contains a special file: {}
- legacy audit tree contains a special file: {}
- legacy capsule directory is not a regular directory: {}
- legacy capsule entry is not a regular directory: {}
- capsule projection contains a special file: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/0119e15135850381.
Report an issue: GitHub.