openai/codex · error · io::Error

InvalidInput

InvalidInput

Error message

permissions profile requests filesystem writes outside the workspace root, which is not supported until the runtime enforces FileSystemSandboxPolicy directly

What it means

Thrown while converting a restricted FileSystemSandbox permissions profile into the legacy SandboxPolicy enum. The legacy policy can only express ReadOnly, WorkspaceWrite (writable cwd plus extra roots), or full access; if a profile grants write access outside the workspace root while the workspace root itself is not writable, no legacy policy can represent that shape, so the conversion fails fast with ErrorKind::InvalidInput instead of silently weakening the sandbox.

Source

Thrown at codex-rs/protocol/src/permissions.rs:1471

                    });
                }

                if workspace_root_writable {
                    SandboxPolicy::WorkspaceWrite {
                        writable_roots: dedup_absolute_paths(
                            writable_roots,
                            /*normalize_effective_paths*/ false,
                        ),
                        network_access: network_policy.is_enabled(),
                        exclude_tmpdir_env_var: !tmpdir_writable,
                        exclude_slash_tmp: !slash_tmp_writable,
                    }
                } else if unbridgeable_root_write
                    || !writable_roots.is_empty()
                    || tmpdir_writable
                    || (cfg!(unix) && slash_tmp_writable)
                {
                    return Err(io::Error::new(
                        io::ErrorKind::InvalidInput,
                        "permissions profile requests filesystem writes outside the workspace root, which is not supported until the runtime enforces FileSystemSandboxPolicy directly",
                    ));
                } else {
                    SandboxPolicy::ReadOnly {
                        network_access: network_policy.is_enabled(),
                    }
                }
            }
        })
    }

    fn resolved_entries_with_cwd(&self, cwd: &Path) -> Vec<ResolvedFileSystemEntry> {
        let cwd_absolute = AbsolutePathBuf::from_absolute_path(cwd).ok();
        self.entries
            .iter()
            .filter_map(|entry| {
                resolve_entry_path(&entry.path, cwd_absolute.as_ref()).map(|path| {

View on GitHub (pinned to 339751715c)

Solutions

  1. Add a write grant for the workspace root (write on ProjectRoots or on the cwd path) so the profile maps to WorkspaceWrite; extra writable roots are then permitted
  2. Remove the out-of-root write grants (Root, other absolute paths, Tmpdir, SlashTmp) so the profile maps to ReadOnly
  3. If whole-disk write is truly intended, use an unrestricted / full-disk-write profile instead of Restricted
  4. If restricted-mode writes outside the root are required, consume the profile's FileSystemSandboxPolicy directly rather than converting to legacy SandboxPolicy

Example fix

// before: restricted profile, no project-root write
- path: { special: tmpdir }
  access: write
// after: add project-root write so the profile maps to WorkspaceWrite
- path: { special: project_roots }
  access: write
- path: { special: tmpdir }
  access: write
Defensive patterns

Strategy: validation

Validate before calling

let cwd_abs = AbsolutePathBuf::from_absolute_path(cwd).ok();
let mut root_writable = false;
let mut outside_write = false;
for e in &profile.entries {
    if !e.access.can_write() { continue; }
    match resolve_entry_path(&e.path, cwd_abs.as_ref()) {
        Some(p) if cwd_abs.as_ref() == Some(&p) => root_writable = true,
        Some(_) => outside_write = true,
        None => if let FileSystemPath::Special { value } = &e.path {
            if matches!(value, FileSystemSpecialPath::Root | FileSystemSpecialPath::Tmpdir | FileSystemSpecialPath::SlashTmp) { outside_write = true; }
        },
    }
}
if !root_writable && outside_write { return Err(invalid_profile()); }

Try / catch

let policy = match profile.try_into() {
    Ok(p) => p,
    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => {
        return Err(anyhow::anyhow!("invalid permissions profile: {e}"))
    }
    Err(e) => return Err(e.into()),
};

Prevention

When it happens

Trigger: Converting a FileSystemSandboxKind::Restricted profile whose entries grant Write to FileSystemSpecialPath::Root, to any absolute path other than the cwd, to Tmpdir, or (on unix) to SlashTmp - while no entry grants write on the cwd / ProjectRoots, so workspace_root_writable stays false.

Common situations: A permissions profile that grants write to a scratch or temp directory but leaves the project itself read-only; older profiles written when the runtime enforced FileSystemSandboxPolicy directly being fed through the legacy conversion path; hand-edited YAML with a stray out-of-root write entry.

Related errors


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