astrid-runtime/astrid · error
cache contains a redirect or special entry: {}
Error message
cache contains a redirect or special entry: {} What it means
validate_cache_tree recursively walks the materialization cache and rejects any entry that is a symlink or neither a directory nor a regular file (fifos, sockets, devices). This enforces that the cache tree contains only plain materialized content, protecting against redirect attacks and special files inside a tree that will later be deleted or executed from. It recurses into subdirectories and is also called by itself.
Source
Thrown at crates/astrid-capsule-install/src/paths.rs:208
let path = entry
.context("read capsule materialization cache entry")?
.path();
remove_cache_tree(&path)?;
}
Ok(())
}
fn validate_cache_tree(path: &Path) -> anyhow::Result<()> {
astrid_core::platform_fs::verify_no_redirects(path)
.with_context(|| format!("verify cache path {}", path.display()))?;
for entry in std::fs::read_dir(path).with_context(|| format!("read {}", path.display()))? {
let path = entry
.with_context(|| format!("read cache entry under {}", path.display()))?
.path();
let metadata = std::fs::symlink_metadata(&path)
.with_context(|| format!("inspect {}", path.display()))?;
if metadata.file_type().is_symlink() || (!metadata.is_dir() && !metadata.is_file()) {
anyhow::bail!(
"cache contains a redirect or special entry: {}",
path.display()
);
}
if metadata.is_dir() {
validate_cache_tree(&path)?;
} else {
astrid_core::platform_fs::verify_no_redirects(&path)
.with_context(|| format!("verify cache file {}", path.display()))?;
}
}
Ok(())
}
fn remove_cache_tree(path: &Path) -> anyhow::Result<()> {
let metadata = std::fs::symlink_metadata(path)
.with_context(|| format!("inspect cache path {}", path.display()))?;
if metadata.file_type().is_symlink() || (!metadata.is_dir() && !metadata.is_file()) {View on GitHub (pinned to affd8760f4)
Solutions
- Inspect the reported path (`ls -la`) and delete the offending symlink/special entry, then re-run the cleanup
- Purge and rebuild the whole cache directory after verifying the root itself is safe
- Find the process that created the non-regular entry and stop it from writing into the cache
- Restrict write access to the cache directory to the runtime user only
Example fix
// before $ find ~/.cache/astrid/capsules -type l # shows link -> /etc // after $ rm ~/.cache/astrid/capsules/<offending-link> # or full reset: $ rm -rf ~/.cache/astrid/capsules && mkdir ~/.cache/astrid/capsules
Defensive patterns
Strategy: validation
Validate before calling
fn cache_tree_has_only_regular_entries(root: &Path) -> anyhow::Result<bool> {
for entry in std::fs::read_dir(root)? {
let p = entry?.path();
let m = std::fs::symlink_metadata(&p)?;
if m.file_type().is_symlink() || (!m.is_dir() && !m.is_file()) {
return Ok(false);
}
if m.is_dir() && !cache_tree_has_only_regular_entries(&p)? { return Ok(false); }
}
Ok(true)
} Type guard
fn is_plain_entry(p: &Path) -> bool {
std::fs::symlink_metadata(p).map(|m| !m.file_type().is_symlink() && (m.is_dir() || m.is_file())).unwrap_or(false)
} Try / catch
if let Err(e) = clear_capsule_materialization_cache(&root) {
if e.to_string().contains("redirect or special entry") {
// extract the offending path, delete it, retry
} else { return Err(e); }
} Prevention
- Restrict cache directory write access to the runtime user only
- Scan for symlinks/special files in shared cache dirs on startup
- Ensure build tooling never leaves sockets or fifos under the cache
- After restoring caches from backups, re-verify the tree before cleanup
When it happens
Trigger: A symlink planted inside the cache (e.g. pointing to /etc) or a socket/fifo/device node appearing under the cache root when clear_capsule_materialization_cache calls validate_cache_tree, or when validate_cache_tree is invoked recursively.
Common situations: Malicious or curious tooling creating links inside the shared cache directory; build processes that leave sockets/fifos in cache paths; restored-from-backup caches containing symlinks; crash residue from another program.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- symlink {} resolves outside the capsule source root ({}); re
- capsule materialization cache is redirected or not a directo
- cache changed to a redirect or special entry: {}
- capsule cache path is redirected: {error}
- PermissionDenied
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/46ebc24f2b72f0fe.
Report an issue: GitHub.