openai / openai/codex

Windows: thread/start fails with os error 206 ("failed to load AGENTS.md instructions") - deny-read glob expansion overflows the sandbox helper command line

Open
#41,809 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

app app-server bug config sandbox windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of the Codex App are you using (From "About Codex" dialog)?

Codex App 26.825.6671.0 (MSIX), app-server client_version 26.825.51511, codex-rs client_version 0.151.0 (from logs_2.sqlite).

What subscription do you have?

ChatGPT workspace account with enterprise-managed Codex policies (cloud-delivered requirements bundle).

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64 (Windows 11 Pro). HKLM\...\FileSystem\LongPathsEnabled = 0 (note: not the cause — see analysis; the 32,767-char command-line limit applies regardless).

What issue are you seeing?

Every attempt to start a new chat on environment local fails after a ~40 s stall with:

Error creating chat
error creating thread: Fatal error: Failed to initialize session: failed to load AGENTS.md instructions for environment local: The filename or extension is too long. (os error 206)

From ~/.codex/logs_2.sqlite (redacted):

[ERROR] codex_core::session core\src\session\mod.rs:791
app_server.request{... rpc.method="thread/start" ... app_server.client_version="26.825.51511"}
  :app_server.thread_start.create_thread{...}:thread_spawn{...}:
Failed to create session: failed to load AGENTS.md instructions for environment `local`:
The filename or extension is too long. (os error 206)

Reproduces on 100% of thread starts on this machine (two consecutive attempts logged identically, ~42 s and ~26 s after session_init). The project folder is a freshly auto-created, empty Documents\Codex\<date>\<slug> directory — the failure is unrelated to project contents.

What steps can reproduce the bug?

Preconditions:

  1. Windows 11 machine with a normally-used Chrome profile (tens of thousands of files under %LOCALAPPDATA%\Google\Chrome).
  2. Enterprise-managed requirements that (a) allow only a restricted managed permission profile (no full-disk read, so :root = "deny"), (b) use the elevated Windows sandbox ([windows] sandbox = "elevated"), and (c) contain recursive deny-read globs over large directory trees. Minimal example:
default_permissions = "managed_net"

[allowed_permission_profiles]
managed_net = true

[permissions.managed_net]
extends = ":workspace"

[permissions.managed_net.filesystem]
glob_scan_max_depth = 8
":root" = "deny"
":minimal" = "read"

[permissions.filesystem]
deny_read = [
  "~/AppData/Local/Google/Chrome/**",
]

Steps:

  1. Open the Codex App, start any new chat on environment local (an empty project folder suffices).
  2. Wait ~40 s → the "Error creating chat … os error 206" failure above.
What is the expected behavior?

The session starts and the deny-read policy is enforced. Whether the sandbox helper can be spawned should not depend on how many pre-existing files happen to match a deny glob on the host. Ideally an AGENTS.md discovery failure would also not hard-fail thread creation (or at least produce an actionable error instead of a raw OS error).

Additional information

Root-cause analysis against codex-rs @ a9519cb (current main; the failing code paths match the shipped app's behavior and log lines):

  1. thread/start → session init loads AGENTS.md instructions. Under a managed profile without full disk read access, discovery runs through the sandboxed filesystem, and — unlike the default profiles where discovery errors are only logged — any error is fatal to session creation: core/src/agents_md.rs#L94-L108. This is why only enterprise-managed installs surface this as "can't create any chat".
  2. Each sandboxed FS operation (even the get_metadata probes for AGENTS.md) spawns a sandboxed helper process: exec-server/src/sandboxed_file_system.rs#L193-L221exec-server/src/fs_sandbox.rs#L75-L121.
  3. The Windows direct-spawn transform resolves filesystem overrides for the elevated backend: sandboxing/src/manager.rs#L572-L627sandboxing/src/windows.rs#L213-L242.
  4. Because Windows ACLs can't express globs, every deny-read glob is snapshot-expanded into concrete matching paths by scanning the filesystem (ripgrep or the fallback walker, capped by glob_scan_max_depth): windows-sandbox-rs/src/deny_read_resolver.rs#L31-L98. This scan is the ~40 s stall.
  5. The full expanded path list is JSON-serialized into a single command-line argument for the sandbox wrapper: windows-sandbox-rs/src/wrapper.rs#L105-L111 (DENY_READ_PATHS_JSON_FLAG), alongside the serialized permission profile and env JSON.
  6. Windows caps a CreateProcessW command line at 32,767 UTF-16 chars. When the expansion is large, Command::spawn fails with ERROR_FILENAME_EXCED_RANGE = "The filename or extension is too long. (os error 206)". That raw error is stringified at exec-server/src/fs_sandbox.rs#L484-L489, travels back as the JSON-RPC error message, and is re-wrapped once by agents_md.rs — producing exactly the observed message. (The alternative error sites in this path — walker abort, ripgrep failure, transform errors — all wrap the message with prefixes like failed to enumerate unreadable glob paths under …; the observed error has no such prefix, so the bare os error can only come from the helper spawn.)

Measured on the affected machine (items within glob_scan_max_depth = 8, full-path character totals):

deny glob target items path chars
~/AppData/Local/Google/Chrome/** 23,603 3,573,708
~/.docker/** 4,363 395,906
~/AppData/Roaming/Mozilla/Firefox/** 2,292 371,747
~/.kube/** 2,148 242,446

JSON-escaped (backslashes doubled, quotes and commas added) that is roughly 4.8 MB in one argv element vs. the 32,767-char limit — >100× over. Session creation can never succeed on such hosts, and any sandboxed command would hit the same wall even if AGENTS.md discovery were skipped.

Related hazards spotted in the same area:

  • The elevated setup/refresh path has the same ceiling: the whole ElevationPayload (including deny_read_paths) is base64-encoded into a single argument in windows-sandbox-rs/src/setup.rs#L322-L375.
  • With ripgrep unavailable, the fallback walker aborts the whole snapshot on any unexpected I/O error, including path-too-long (error 206) on LongPathsEnabled=0 hosts: windows-sandbox-rs/src/deny_read_walker.rs#L131-L147.
  • Possibly the same scale problem underlies other Windows deny-read ACL reports (#36087, #32525, #30758 — different symptom, same subsystem).

Potential approaches to a fix (per the contributing guide, offered as analysis rather than a PR):

  1. Transport: pass the large JSON payloads (deny paths, permission profile, env) to the wrapper via stdin or a temp file instead of argv; same for the elevated setup payload (a short file path survives ShellExecute/UAC where stdin cannot).
  2. Scale: don't enumerate beneath a directory that is already deny-matched — an inherited deny ACE on the directory covers the subtree, so descendants in the snapshot are redundant. A dir/** glob could short-circuit to its literal root without scanning at all, which would also remove the ~40 s per-session scan.
  3. Resilience: consider degrading AGENTS.md discovery failures to a warning under sandboxed profiles too, or at least attaching context (which operation/paths) to the fatal error instead of a bare OS error.

Admin workaround that restores service immediately: in managed policies, use exact directory paths (no trailing /**) for directory-shaped deny-read entries, e.g. "~/AppData/Local/Google/Chrome" instead of "~/AppData/Local/Google/Chrome/**" — exact roots are passed through without expansion (deny_read_resolver.rs#L24-L40) and a directory deny covers its subtree. Verified working on the affected machine.

🤖 Root-cause analysis generated from local ~/.codex logs and codex-rs sources @ a9519cb.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with windows-sandbox-rs/src/deny_read_resolver.rs and wrapper.rs, then trace the payload through sandboxing/src/windows.rs and exec-server/src/fs_sandbox.rs. Reproduce with the managed profile and a large recursive deny-read glob. Done means Windows session and sandbox-helper startup no longer fail with os error 206 while the deny-read policy remains enforced.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools, operating-systems, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.