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
- 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
- Remove the out-of-root write grants (Root, other absolute paths, Tmpdir, SlashTmp) so the profile maps to ReadOnly
- If whole-disk write is truly intended, use an unrestricted / full-disk-write profile instead of Restricted
- 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
- Always pair out-of-root write grants with a workspace-root write grant
- Convert representative profiles in unit tests / CI to catch invalid shapes early
- Surface InvalidInput from this conversion as a user-facing configuration error, not a runtime fault
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
- failed to exec bundled bubblewrap {} via {fd_path}: {err}
- externally enforced filesystem permissions cannot be interse
- platform-default filesystem permissions cannot be intersecte
- unsupported permission path: {0}
- Unsupported platform: ${platform} (${arch})
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/e1f6743315501ec7.
Report an issue: GitHub.