openai/codex · error · PermissionIntersectionError

unsupported permission path: {0}

Error message

unsupported permission path: {0}

What it means

PermissionIntersectionError::UnsupportedPath(String) (codex-rs/protocol/src/permission_profile_intersection.rs:27-28) is the fail-closed catch-all of intersect_effective_permission_profiles for shapes it cannot merge safely; the payload names the offending path or shape. Grounded raise sites: a non-absolute cwd (line 47); unmaterialized workspace permissions - ProjectRoots (57-63) or a project-roots glob (64-68); tmpdir restrictions lacking executor-local bindings (136-140); non-metadata optional permissions (189-192); symlinked read restrictions (308-313); non-Deny or skip-missing glob permissions (316-322); paths that fail to_abs_path/canonicalize because they are missing on disk (283-297); other unsupported Special values (342-346).

Source

Thrown at codex-rs/protocol/src/permission_profile_intersection.rs:27

use crate::permissions::FileSystemPath;
use crate::permissions::FileSystemSandboxEntry;
use crate::permissions::FileSystemSandboxKind;
use crate::permissions::FileSystemSandboxPolicy;
use crate::permissions::FileSystemSpecialPath;
use crate::permissions::NetworkSandboxPolicy;
use crate::permissions::PROTECTED_METADATA_PATH_NAMES;
use crate::permissions::ReadDenyMatcher;
use crate::permissions::default_read_only_subpaths_for_writable_root;
use crate::permissions::project_roots_glob_pattern;

/// A policy cannot be intersected without weakening either input.
#[derive(Clone, Debug, Eq, Error, PartialEq)]
pub enum PermissionIntersectionError {
    #[error("externally enforced filesystem permissions cannot be intersected safely")]
    ExternalSandbox,
    #[error("platform-default filesystem permissions cannot be intersected safely")]
    PlatformDefaults,
    #[error("unsupported permission path: {0}")]
    UnsupportedPath(String),
}

/// Intersects already-effective filesystem permissions and network access.
///
/// Both profiles must already be materialized for the same local executor and
/// cwd. Concrete grant paths are canonicalized before comparison and in the
/// result, so symlinks cannot acquire authority beyond either input.
/// Unsupported policy shapes fail closed.
pub fn intersect_effective_permission_profiles(
    authority: &PermissionProfile,
    requested: &PermissionProfile,
    cwd: &Path,
) -> Result<PermissionProfile, PermissionIntersectionError> {
    if matches!(authority, PermissionProfile::External { .. })
        || matches!(requested, PermissionProfile::External { .. })
    {
        return Err(PermissionIntersectionError::ExternalSandbox);

View on GitHub (pinned to 339751715c)

Solutions

  1. Read the payload - it names the exact shape ('workspace permissions must already be materialized', 'symlinked restriction: ...', 'glob permissions: ...', or a path that failed canonicalization).
  2. Pass an absolute cwd and make sure concrete entry paths exist on disk.
  3. Materialize ProjectRoots/workspace permissions and expand project-roots globs into concrete entries before intersecting.
  4. Remove or convert unsupported shapes: non-deny globs, optional non-metadata entries, symlinked restrictions, and tmpdir restrictions without executor-local bindings.

Example fix

// before:
let merged = intersect_effective_permission_profiles(&a, &b, Path::new("repo"))?;
// relative cwd -> UnsupportedPath error

// after:
let cwd = std::env::current_dir()?; // absolute
let merged = intersect_effective_permission_profiles(&a, &b, &cwd)?;
Defensive patterns

Strategy: validation

Validate before calling

let cwd = std::env::current_dir()?; // must be absolute, not relative
for p in [authority, requested] {
    for entry in &p.file_system_sandbox_policy().entries {
        if let FileSystemPath::Path { path } = &entry.path {
            std::fs::canonicalize(path.to_abs_path()?)?; // must exist on disk
        }
    }
}

Type guard

fn is_unsupported_path(err: &PermissionIntersectionError) -> bool {
    matches!(err, PermissionIntersectionError::UnsupportedPath(_))
}

Try / catch

Err(PermissionIntersectionError::UnsupportedPath(what)) => {
    // `what` names the path or shape; fix the profile or cwd and retry
}

Prevention

When it happens

Trigger: Intersecting profiles that contain any of: a relative cwd, an unmaterialized workspace/ProjectRoots entry or project-roots glob, a skip-missing entry that is not read-only metadata, a read restriction placed through a symlink, a non-deny glob grant, or a concrete path that does not exist so canonicalize fails.

Common situations: Forgetting to materialize workspace permissions before merging; config-driven glob grants; optional permissions for not-yet-created directories; symlinked project layouts; accidentally passing a relative cwd.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/f18d1611f45bac56. Report an issue: GitHub.