astrid-runtime/astrid · error
inspect capsule projection {}: {error}
Error message
inspect capsule projection {}: {error} What it means
Thrown when `std::fs::symlink_metadata` fails for an entry in the capsule projection during the inventory walk. The metadata is needed to classify the entry (file/dir/symlink); if it cannot be inspected the walk cannot continue safely. The OS error is wrapped with the path.
Source
Thrown at crates/astrid-kernel/src/lib.rs:1636
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() {
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()
);View on GitHub (pinned to affd8760f4)
Solutions
- Retry the inventory walk after the concurrent mutation settles.
- Ensure no other process deletes/modifies projection entries during the walk.
- Check filesystem health and permissions for the reported path.
- Capture the wrapped io::Error source for the exact OS errno.
Defensive patterns
Strategy: retry
Try / catch
match build_inventory(root) {
Err(e) if e.to_string().contains("inspect capsule projection") => build_inventory(root),
other => other,
} Prevention
- Prevent concurrent deletion of projection entries during walks.
- Use local filesystems for projections when possible.
- Capture the io::Error source to distinguish races from real IO faults.
When it happens
Trigger: The entry vanished between `read_dir` and `symlink_metadata` (TOCTOU race), or lstat fails due to permissions or IO errors on the filesystem.
Common situations: Concurrent deletion during inventory; files on a failing or network mount; permission bits changed mid-walk.
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
- read capsule projection entry: {error}
- workspace capsule manifest changed while it was being read:
- read capsule projection {}: {error}
- inspect projected file {}: {error}
- read projected file {}: {error}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/de485c57dccc33c9.
Report an issue: GitHub.