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

  1. Create the directory before calling: fs::create_dir_all(path)
  2. Call fs::canonicalize first and skip/report paths that fail
  3. Filter extra_read_paths to those with path.exists() when absence is acceptable
  4. 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

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


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/0016deb46e0bf8bd. Report an issue: GitHub.