[macOS] Desktop main process holds ~243 FDs across three Chromium storage profiles and hits the default 256 limit
What version of the Codex App are you using (From “About Codex” dialog)?
26.814.41407 (CFBundleVersion 6720, bundle ID com.openai.codex)
What subscription do you have?
ChatGPT subscription
What platform is your computer?
Darwin 27.0.0 arm64 arm
macOS 27.0 (26A5416b)
What issue are you seeing?
Codex Desktop (currently installed as /Applications/ChatGPT.app, bundle ID com.openai.codex) can reach macOS's default GUI soft limit of 256 file descriptors in its Electron/Chromium main process. Once this happens, ordinary subprocess creation fails and the GUI becomes unstable or exits.
The app logs recorded the following while the Electron message handler was trying to run git config:
failed to spawn process: Too many open files (os error 24)
The same incident also caused configuration and thread metadata operations to fail. The system-wide file table was not exhausted.
After relaunching and temporarily raising the GUI launchd soft limit, the main process still settles at 243 numeric FDs, showing that its normal operating baseline is already only 13 descriptors below the default macOS GUI limit.
Current main-process FD breakdown:
183 REG
19 unix
14 PIPE
11 KQUEUE
10 DIR
5 CHR
1 NPOLICY
---
243 total
The dominant source is three separate Chromium/Electron storage-profile trees:
63 ~/Library/Application Support/Codex/Default/... (excluding the partition subtree below)
48 ~/Library/Application Support/Codex/Default/Partitions/codex-browser-app/...
44 ~/Library/Application Support/Codex/codex-browser-app/...
---
155 FDs
These include many independent LevelDB and SQLite sets such as LOCK, LOG, MANIFEST-000001, 000003.log, GCM Store, History, Favicons, Web Data, SharedStorage, BrowsingTopicsSiteData, WAL/SHM/journal files, and Chromium cache indexes.
This is not a system-wide exhaustion event:
kern.num_files: ~9,300
kern.maxfiles: 122,880
kern.maxfilesperproc: 61,440
What steps can reproduce the bug?
The original failure occurred with the normal macOS GUI soft limit of 256.
- Launch Codex Desktop normally from Finder/Dock on macOS.
- Open and work in tasks that use Git repositories and the in-app browser/tools.
- Allow the main process to initialize its persistent Chromium storage partitions.
- Inspect the main process with
lsof -p <main_pid>; in my reproduction it reached 243 numeric descriptors. - Continue normal task activity that spawns short-lived processes such as
git config. - The additional files/pipes needed for spawn can cross 256, producing
EMFILE/Too many open files (os error 24)and destabilizing the GUI.
The exact time to failure varies with task/browser activity. Relaunching clears the immediate failure, but the baseline returns close to the limit.
What is the expected behavior?
The Desktop main process should retain enough FD headroom for normal subprocess and IPC bursts on a default macOS GUI launch. Persistent browser sessions that are no longer needed should release their resources, or the app should raise its own RLIMIT_NOFILE to a safe value during startup.
Additional information
I checked for common leak signatures:
- Seven samples over about one minute stayed flat at 243 FDs, so I did not observe a short-term monotonic leak in that interval.
- There was no widespread duplication of the exact same path.
- Only one open-but-unlinked Chromium
BrowserMetrics-*.pmafile was present, which does not explain the count. - The app-server child had 112 FDs; the 243-FD ceiling risk described here is specifically in the Electron/Chromium main process.
This appears distinct from existing reports:
- #26984 reports a cumulative MCP stdio leak with 186 PIPE FDs. This process has only 14 PIPE FDs and is dominated by 183 regular files.
- #26117 concerns thousands of descriptors retained by macOS
syspolicyd. Here,syspolicydand the global file table were healthy; the Codex/ChatGPT main process itself held 243 descriptors. - #36755 describes a transient skill-loader concurrency burst. That may be another way to hit a low limit, but it does not explain this main process's persistent Chromium-profile baseline.
Questions for maintainers:
- Are all three persistent storage roots intended to coexist in the main process?
- Can the default session and the two
codex-browser-appstorage roots share or lazily close database handles? - Could the macOS app raise its per-process soft limit toward the existing hard limit at startup as a defensive measure?
A temporary workaround is raising the GUI launchd soft limit; after doing so, the app works normally. This masks the immediate failure but does not reduce the 243-FD baseline.
1 Comment
Data point from an independent diagnosis of the same symptom, same class of build (26.814.41407): the ~243-handle Chromium storage census reproduces, but on my machine the Electron main was not the process that died — its fd numbers ran past 306, so its limit had been raised (Chromium bumps the browser process to 8192 in
BrowserMainLoop::EarlyInitialization). The process hitting 256 was the Rustcodex app-server(fd numbers frozen at exactly 255, all 650 unified-log EMFILE lines attributed to it), filled mostly by unreaped MCP helper pipes (#38925, #26984).Quick discriminator for anyone else here — check the fd numbers, not the count:
lsof -p <PID>and look at the highest numeric FD. Frozen at ≤255 → that process filled a 256 table; numbers past 256 → its limit was raised and it is not the one failing.Your suggested fix (raise the per-process soft limit at startup) worked when applied externally today — immediate verification only, no long-term soak yet. Wrapper + verification method: https://github.com/lazforprez/codex-fd-exhaustion-fix