openai/codex · error · PermissionIntersectionError
platform-default filesystem permissions cannot be intersecte
Error message
platform-default filesystem permissions cannot be intersected safely
What it means
PermissionIntersectionError::PlatformDefaults (codex-rs/protocol/src/permission_profile_intersection.rs:25-26) is raised inside normalize_policy (lines 277-279, and for FileSystemSpecialPath::Minimal at 339-341) when a policy being intersected still includes platform defaults - include_platform_defaults() is true or the Minimal special path is present. Platform defaults resolve per-OS and per-executor, so an intersection could silently diverge from what either input actually grants; the merge fails closed.
Source
Thrown at codex-rs/protocol/src/permission_profile_intersection.rs:25
use crate::models::PermissionProfile;
use crate::permissions::FileSystemAccessMode;
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 { .. })View on GitHub (pinned to 339751715c)
Solutions
- Materialize platform defaults for the concrete executor and OS into explicit policy entries before intersecting.
- Rebuild the profile with include_platform_defaults off once defaults are expanded.
- Replace FileSystemSpecialPath::Minimal with its concrete entry set before merging.
Example fix
// before: let merged = intersect_effective_permission_profiles(&a, &b, &cwd)?; // a.include_platform_defaults() == true -> PlatformDefaults error // after: expand defaults into concrete entries, then intersect let a = materialize_platform_defaults(a, &cwd)?; // no platform defaults left let merged = intersect_effective_permission_profiles(&a, &b, &cwd)?;
Defensive patterns
Strategy: validation
Validate before calling
if authority.file_system_sandbox_policy().include_platform_defaults()
|| requested.file_system_sandbox_policy().include_platform_defaults()
{
// expand platform defaults into explicit entries before intersecting
} Type guard
fn includes_platform_defaults(p: &PermissionProfile) -> bool {
p.file_system_sandbox_policy().include_platform_defaults()
} Try / catch
Err(PermissionIntersectionError::PlatformDefaults) => {
// expand defaults for this executor and retry the intersection once
} Prevention
- Always materialize profiles for the target executor before merging.
- Keep intersection inputs free of Minimal and platform-default markers.
- Add tests covering the platform-default path on each supported OS.
When it happens
Trigger: intersect_effective_permission_profiles on two differing, non-Unrestricted, non-Disabled profiles where either side was built with include_platform_defaults = true or carries the Minimal special path.
Common situations: User configs layering grants on top of OS defaults; cross-platform configs where defaults differ; profiles forwarded to intersection without being materialized for the concrete executor.
Related errors
- externally enforced filesystem permissions cannot be interse
- unsupported permission path: {0}
- `approval_policy = "never"` cannot be used because requireme
- I/O error while reading memories: {0}
- failed to exec bundled bubblewrap {} via {fd_path}: {err}
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/81ef4be0210ae302.
Report an issue: GitHub.