astrid-runtime/astrid · error
inspect projected file {}: {error}
Error message
inspect projected file {}: {error} What it means
Thrown by `read_projection_file_nofollow` when `symlink_metadata` on a projected file path fails. The function reads projected files without following symlinks and must first confirm the path is a regular file; failing to stat it aborts the read. The OS error is wrapped with the path.
Source
Thrown at crates/astrid-kernel/src/lib.rs:1670
"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| {
anyhow::anyhow!("inspect projected file {}: {error}", path.display())
})?;
if metadata.file_type().is_symlink() || !metadata.is_file() {
anyhow::bail!(
"projected path is redirected or not a regular file: {}",
path.display()
);
}
let mut file = open_projection_file_nofollow(path)?;
let mut bytes = Vec::new();
file.read_to_end(&mut bytes)
.map_err(|error| anyhow::anyhow!("read projected file {}: {error}", path.display()))?;
if file.metadata()?.len() != metadata.len() || bytes.len() as u64 != metadata.len() {
anyhow::bail!("projected file changed while read: {}", path.display());
}
Ok(bytes)
}
/// Load a capsule into the Kernel from a directory containing a Capsule.tomlView on GitHub (pinned to affd8760f4)
Solutions
- Verify the path exists and is accessible before reading (the inventory path is authoritative).
- Retry the read if the file was concurrently replaced or removed.
- Check file permissions and ownership on the projection.
- Inspect the wrapped io::Error source for the exact OS reason.
Defensive patterns
Strategy: validation
Validate before calling
let meta = std::fs::symlink_metadata(path)?;
anyhow::ensure!(meta.is_file(), "not a regular file: {}", path.display()); Type guard
fn is_regular_file_nofollow(p: &Path) -> bool {
std::fs::symlink_metadata(p).map(|m| m.is_file()).unwrap_or(false)
} Try / catch
match read_projection_file_nofollow(path) {
Err(e) if e.to_string().contains("inspect projected file") => {
// path vanished or unreadable: re-derive from inventory or retry
}
other => other,
} Prevention
- Re-read the inventory instead of caching absolute paths.
- Check symlink_metadata before direct reads.
- Watch for TOCTOU races with concurrent writers.
When it happens
Trigger: Reading a projected file whose path does not exist, is unreadable, or whose lstat fails due to IO error; race where the file is deleted just before reading.
Common situations: Projection root changed underneath a running read; wrong path computed from inventory; permissions tightened on the file; flaky network filesystem.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- legacy state source is redirected: {}
- legacy state source contains a redirect: {}
- workspace capsule portal is not a regular directory: {}
- workspace capsule portal contains a redirect: {}
- directory symlink {} not allowed in capsule source tree (ref
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/b132b2c71fe60b24.
Report an issue: GitHub.