astrid-runtime/astrid · error
process write path does not exist: {}
Error message
process write path does not exist: {} What it means
wrap_with_process_paths validates each extra write path for sandbox interpolation and requires it to exist (io::ErrorKind::NotFound). Write grants in the sandbox profile must correspond to real locations, so a missing path is rejected instead of producing an ineffective grant.
Source
Thrown at crates/astrid-workspace/src/sandbox/mod.rs:275
// 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,
// UTF-8, SBPL-safe — because on macOS it is interpolated into the Seatbelt
// profile; then it must EXIST, since a path that does not exist is a wiring
// bug, not a no-op (silently skipping it leaves the child un-denied). The
// deny is security-critical, so either failure fails the spawn closed.
for masked in extra_masks {
let _ = validate_sandbox_str(masked, "workspace CoW mask")?;
if !masked.exists() {
return Err(io::Error::new(
io::ErrorKind::NotFound,View on GitHub (pinned to affd8760f4)
Solutions
- Pre-create the path with fs::create_dir_all(path) before calling wrap_with_process_paths
- For files, create the parent directory and touch the file if the grant targets a file
- Filter or canonicalize the write paths first, handling missing ones explicitly
- Correct the configured path so it matches an existing location
Example fix
// before
wrap_with_process_paths(&ws, &[], &[PathBuf::from("/tmp/myapp/out")])?;
// after
let out = PathBuf::from("/tmp/myapp/out");
std::fs::create_dir_all(&out)?;
wrap_with_process_paths(&ws, &[], &[out])?; Defensive patterns
Strategy: validation
Validate before calling
for p in write_paths { if !p.exists() { std::fs::create_dir_all(p)?; } } Type guard
fn writable_target_exists(p: &Path) -> bool { p.exists() } Try / catch
match wrap_with_process_paths(&ws, &[], &write_paths) { Err(e) if e.kind() == io::ErrorKind::NotFound => { /* create_dir_all the reported path and retry once */ }, other => other, } Prevention
- Create output directories before configuring the sandbox
- Validate write targets at pipeline start, before any long-running setup
- Ensure mounted volumes are attached before the sandbox profile is built
When it happens
Trigger: Calling the public wrap_with_process_paths with an extra_write_paths entry that is a valid absolute UTF-8 path but does not exist on disk — e.g. an output directory not yet created, or a path deleted after configuration was written.
Common situations: Output/build directories that the tool expects the caller to pre-create; paths on a mounted volume not yet mounted; typo'd absolute paths in config; CI environments missing a directory created by an earlier step.
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 read 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/0ab38ec1ec20cf07.
Report an issue: GitHub.