Sandbox denial errors don't tell the agent which paths are writable
What variant of Codex are you using?
CLI (via codex-acp agent runtime)
What feature would you like to see?
The problem
When the sandbox blocks a write to /tmp or $TMPDIR, the error message contains the raw stderr from the failed command but doesn't include any information about which paths the agent can write to. The agent has no way to self-correct — it doesn't know whether to try the workspace directory, a subdirectory, or give up entirely.
Observed in production (codex-acp) when Jest tried to write its cache to $TMPDIR:
ERROR codex_core::tools::router:
error=exec_command failed for `/bin/zsh -lc "npm test -- --runInBand"`:
SandboxDenied { message: "Error: EPERM: operation not permitted,
open '/private/var/folders/.../T/jest_dy/haste-map-...'" }
The sandbox policy had exclude_tmpdir_env_var: true and exclude_slash_tmp: true, so this denial is correct behavior. But the error gives the agent no hint about what to do instead.
What would help
Include the list of writable paths in the sandbox denial error message. Something like:
Sandbox denied write to '/private/var/folders/.../T/jest_dy/...'.
Writable paths: /Users/dev/project (workspace). Use workspace-relative paths for temp files.
This would let the agent:
- Redirect temp files to the workspace (e.g.
.codex-tmp/) - Set
TMPDIRto a workspace subdirectory before running commands - Understand the constraint without trial and error
Current behavior
UnifiedExecError::SandboxDenied contains the raw command output as message. The writable paths are known at the point where the error is constructed (they come from SandboxPolicy::WorkspaceWrite { writable_roots, .. }), but they're not included in the error.
Impact
Common tools that use temp directories fail silently or with opaque errors under restrictive sandbox policies:
- Jest (
jest-haste-mapwrites to$TMPDIR) - Python (
tempfilemodule defaults to/tmp) - Sort, awk, and other Unix tools that write intermediate files to
/tmp
The agent retries with different approaches, wasting tool calls and tokens, without understanding the actual constraint.
Platform
- Darwin 25.3.0 arm64 arm
- Sandbox: Seatbelt with
exclude_tmpdir_env_var: true,exclude_slash_tmp: true - Observed via
codex-acpagent runtime, codexrust-v0.117.0
Additional information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗