astrid-runtime/astrid · error
process read path does not exist: {}
Error message
process read path does not exist: {} What it means
wrap_with_process_paths validates each extra read path for sandbox interpolation and additionally requires it to exist on disk (io::ErrorKind::NotFound). Extra read paths are granted read access in the sandbox profile, and a nonexistent grant is treated as a configuration error rather than silently ignored.
Source
Thrown at crates/astrid-workspace/src/sandbox/mod.rs:266
injections: &[RoInjection],
extra_masks: &[PathBuf],
extra_read_paths: &[PathBuf],
extra_write_paths: &[PathBuf],
clear_env: bool,
) -> io::Result<Command> {
// Validate on all platforms for defense in depth and API consistency.
// On macOS the validated string is needed for SBPL interpolation.
// On Linux bwrap passes paths as argv entries (no injection risk),
// but we still reject unsafe paths at the API boundary.
let _ = validate_sandbox_str(worktree_path, "worktree path")?;
for inj in injections {
let _ = validate_sandbox_str(&inj.source, "injection source")?;
let _ = validate_sandbox_str(&inj.target, "injection target")?;
}
for path in extra_read_paths {
let _ = validate_sandbox_str(path, "process read path")?;
if !path.exists() {
return Err(io::Error::new(
io::ErrorKind::NotFound,
format!("process read path does not exist: {}", path.display()),
));
}
}
for path in extra_write_paths {
let _ = validate_sandbox_str(path, "process write path")?;
if !path.exists() {
return Err(io::Error::new(
io::ErrorKind::NotFound,
format!("process write path does not exist: {}", path.display()),
));
}
}
// Every caller-supplied mask names copy-on-write bookkeeping the child
// must not reach (the overlayfs upper/work, or the APFS pristine). Each is
// validated exactly like the worktree and injection paths — absolute,View on GitHub (pinned to affd8760f4)
Solutions
- Create the directory before calling: fs::create_dir_all(path)
- Call fs::canonicalize first and skip/report paths that fail
- Filter extra_read_paths to those with path.exists() when absence is acceptable
- Fix the configuration/typo so the path points to an existing location
Example fix
// before
wrap_with_process_paths(&ws, &[PathBuf::from("/var/cache/myapp")], &[])?;
// after
let p = PathBuf::from("/var/cache/myapp");
std::fs::create_dir_all(&p)?;
wrap_with_process_paths(&ws, &[p], &[])?; Defensive patterns
Strategy: validation
Validate before calling
for p in read_paths { if !p.exists() { return Err(io::Error::new(io::ErrorKind::NotFound, format!("missing read path: {}", p.display()))); } } Type guard
fn exists(p: &Path) -> bool { p.exists() } Try / catch
match wrap_with_process_paths(&ws, &read_paths, &[]) { Err(e) if e.kind() == io::ErrorKind::NotFound => { /* create the directory or drop the path, then retry */ }, other => other, } Prevention
- Pre-create all extra read directories with fs::create_dir_all before wrapping a process
- Re-check path existence at startup, not just at configuration load
- Treat existence checks as part of environment setup in CI/containers
When it happens
Trigger: Calling the public wrap_with_process_paths with an extra_read_paths entry that passes validate_sandbox_str (absolute, UTF-8, no forbidden chars) but does not exist at call time — e.g. a stale cache directory, a deleted temp dir, or a typo'd absolute path.
Common situations: Config referencing directories removed between runs; macOS Seatbelt grants for paths like ~/Library/Caches that were cleared; absolute paths typed by hand with a typo; containers where the host path is absent.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- process write path does not exist: {}
- sandbox {label} must be an absolute path, got: {}
- sandbox {label} is not valid UTF-8: {}
- sandbox {label} contains forbidden characters (double-quote,
- capsule source is neither a directory nor a regular file: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/0016deb46e0bf8bd.
Report an issue: GitHub.