astrid-runtime/astrid · error
runtime projection is redirected
Error message
runtime projection is redirected: {} What it means
preflight_projection_entry validates each entry of the runtime projection tree before retirement and rejects any symlink with InvalidData. Like the legacy source checks, this prevents deleting through redirects that could point outside the projection root. It recurses into real directories and is re-entered for every child.
Solutions
- Replace the symlink with a real copy of its target inside the projection tree (cp -aL), or delete the link if it is disposable, then retry.
- Scan first: find <projection-root> -type l to enumerate all redirects before invoking retirement.
- Change deployment processes so projection outputs are always materialized as real files.
Example fix
// before projection/assets -> /opt/shared/assets // after rm projection/assets cp -aL /opt/shared/assets projection/assets
Defensive patterns
Strategy: validation
Validate before calling
fn assert_no_links(root: &Path) -> io::Result<()> {
for e in walkdir_like(root) {
if std::fs::symlink_metadata(&e)?.file_type().is_symlink() {
return Err(io::Error::new(io::ErrorKind::InvalidData, format!("link: {}", e.display())));
}
}
Ok(())
} Type guard
fn is_redirect(p: &Path) -> bool {
std::fs::symlink_metadata(p).map(|m| m.file_type().is_symlink()).unwrap_or(false)
} Try / catch
if let Err(e) = retire_projection_root(&path) {
if e.kind() == io::ErrorKind::InvalidData { eprintln!("materialize or remove link: {e}"); }
} Prevention
- Generate projection files in place rather than linking to shared assets
- Scan with `find <projection-root> -type l` before cleanup
- Make deployment scripts dereference (-h/-L) when copying into the projection tree
When it happens
Trigger: Any file or directory inside the runtime projection root is a symlink when retire_projection_root (or the recursive preflight) runs.
Common situations: Deployment tooling symlinked runtime projection files to shared assets; user replaced generated files with links to their own copies; a partial previous cleanup left links behind.
Related errors
- capsule path escaped source root
- directory symlink not allowed in capsule source tree…
- inspect projected file
- legacy audit source is not a regular directory
- legacy audit tree is redirected or not a directory
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/f5e2bc216780e30f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-core/src/dirs_projection_retirement.rs:44
let path = entry.path();
if entry.file_name() == std::ffi::OsStr::new(CANONICAL_VOLUME) {
continue;
}
let metadata = std::fs::symlink_metadata(&path)?;
if metadata.is_dir() {
crate::dirs::retire_legacy_source_tree(&path)?;
} else {
std::fs::remove_file(&path)?;
}
}
File::open(root)?.sync_all()?;
Ok(())
}
fn preflight_projection_entry(path: &Path) -> io::Result<()> {
let metadata = std::fs::symlink_metadata(path)?;
if metadata.file_type().is_symlink() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("runtime projection is redirected: {}", path.display()),
));
}
if metadata.is_dir() {
for entry in std::fs::read_dir(path)? {
let child = entry?.path();
preflight_projection_entry(&child)?;
}
return Ok(());
}
if !metadata.is_file() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"runtime projection contains a special entry: {}",
path.display()
),View on GitHub (pinned to affd8760f4)