zed-industries/zed · error · std::io::Error

sandbox write grant {} was redirected to {}

Error message

sandbox write grant {} was redirected to {}

What it means

Guard in CanonicalPathBuf::from_canonical on Linux: the directory pinned by O_PATH at grant time is not the same directory the canonical path now points to — something replaced or redirected the grant path (e.g. a directory swapped for a symlink) between canonicalization and pinning. The sandbox refuses to grant writes to a moving target.

Source

Thrown at crates/sandbox/src/util/canonical_path.rs:164

            // the symlink's *own* path (equal to `path`), so the comparison
            // below wouldn't catch it.
            let stat = nix::sys::stat::fstat(&fd).map_err(io::Error::from)?;
            if stat.st_mode & libc::S_IFMT == libc::S_IFLNK {
                return Err(io::Error::new(
                    io::ErrorKind::PermissionDenied,
                    format!(
                        "sandbox write grant {} is a symlink, not a directory",
                        path.display()
                    ),
                ));
            }

            // Load-bearing: the pinned inode's real path must still be exactly
            // the approved canonical path. If any component became a symlink
            // after approval, the fd resolves elsewhere and this diverges.
            let current = std::fs::read_link(format!("/proc/self/fd/{}", fd.as_raw_fd()))?;
            if current != path {
                return Err(io::Error::new(
                    io::ErrorKind::PermissionDenied,
                    format!(
                        "sandbox write grant {} was redirected to {}",
                        path.display(),
                        current.display()
                    ),
                ));
            }

            Ok(Self {
                path,
                fd: std::sync::Arc::new(fd),
            })
        }
        #[cfg(not(any(target_os = "macos", target_os = "linux")))]
        {
            Ok(Self { path })
        }

View on GitHub (pinned to 5a9b9558db)

Solutions

  1. Remove or rename whatever is replacing the grant directory at runtime
  2. Grant the stable canonical location instead of a path that gets swapped
  3. Re-create the grant if a legitimate rename occurred
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/sandbox/src/util/canonical_path.rs:164 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20). Data as JSON: /api/errors/118dc92aa088f730. Report an issue: GitHub.