VS Code Codex extension can allocate about 1M inotify watches on Linux large workspace
What version of the IDE extension are you using?
openai.chatgpt-26.513.21555-linux-x64
What subscription do you have?
ChatGPT Pro
Which IDE are you using?
VS Code 1.120.0
What platform is your computer?
Linux 6.17.0-29-generic x86_64 x86_64
What issue are you seeing?
On Linux, the VS Code Codex extension can drive the user session close to or beyond the inotify watch limit in a large workspace. The high watch count is owned by the VS Code extension host process, not by VS Code's normal file watcher and not by the Codex app-server child.
Observed measurements:
openai.chatgpt disabled in the VS Code Planning profile: about 80k-90k total watches
openai.chatgpt enabled and Codex chats opened/resumed: about 1,048k to 1,234k total watches
VS Code extension host process during bad state: about 900k-1,151k watches
normal VS Code file-watcher process during bad state: about 3k-79k watches
Codex app-server child during bad state: about 213 watches
The impact was desktop-wide inotify exhaustion: logs showed ENOSPC, No space left on device, and OS file watch limit reached, with collateral failures in the Linux desktop session.
Relevant Codex log excerpts from the bad state:
Features enabled ... workspace_dependencies ...
[git-repo-watcher] Starting git repo watcher
codex_file_watcher: failed to watch /etc: OS file watch limit reached
codex_file_watcher: failed to watch /media/S_Drive/projects/strategy-tester/.agents/skills: OS file watch limit reached
codex_app_server_transport::transport: dropping overload response ... outbound queue is full
[git-repo-watcher] Git repo watcher failed ... ENOSPC ... watch '/media/S_Drive/projects/strategy-tester/.git/objects/...'
This workspace has large generated/runtime trees, but they are excluded from VS Code's normal watcher:
"files.watcherExclude": {
"**/.sandcastle/worktrees/**": true,
"**/data/**": true,
"**/logs/**": true
}
The normal VS Code file watcher stayed low, which suggests the Codex extension-side watcher path is bypassing VS Code's files.watcherExclude and/or recursively watching too much Git/workspace state.
What steps can reproduce the bug?
- On Linux, open a large VS Code workspace with the Codex extension enabled.
- Use a workspace with large generated/runtime directories under the repo root. In my case, before local mitigation:
repo total: about 1,071,929 files
logs/: about 716,933 files
data/: about 129,956 files
.sandcastle/worktrees/: about 102,877 files
- Configure VS Code workspace excludes for those large directories, for example:
"files.watcherExclude": {
"**/.sandcastle/worktrees/**": true,
"**/data/**": true,
"**/logs/**": true
}
- Start or resume Codex chats in the VS Code Codex panel. A focused repro opened one existing Codex chat, then opened about 3-4 additional Codex chats.
- Monitor inotify watches:
sudo bash -c 'total=0; for f in /proc/[0-9]*/fdinfo/*; do n=$(grep -c "inotify wd:" "$f" 2>/dev/null || true); total=$((total+n)); done; echo "$total"'
for pid in $(find /proc/*/fd -lname anon_inode:inotify 2>/dev/null | sed 's#/proc/##; s#/fd/.*##' | sort -u); do
watches=$(grep -h "inotify wd:" /proc/$pid/fdinfo/* 2>/dev/null | wc -l)
comm=$(cat /proc/$pid/comm 2>/dev/null)
cmdline=$(tr "\0" " " < /proc/$pid/cmdline 2>/dev/null | cut -c1-220)
printf '%8s %7s %-18s %s\n' "$watches" "$pid" "$comm" "$cmdline"
done | sort -nr | head -20
Observed focused repro:
10:08:58 total_watches=83,205
10:10:08 total_watches=83,205
10:11:18 total_watches=1,234,730
10:12:37 total_watches=1,234,736
10:13:55 total_watches=1,234,736
11:02:12 total_watches=1,234,754
The watches did not release after closing the extra Codex chat tabs/panels, and they remained after about 30 minutes. Developer: Reload Window briefly dropped the count, but the extension restarted and re-triggered the high watcher state.
Disabling workspace_dependencies through the bundled Codex CLI did not prevent this extension-side watcher path. The CLI reported the feature as disabled, but after VS Code reload the extension log still listed workspace_dependencies, started [git-repo-watcher], and the extension host climbed back to about 1.23M total watches.
What is the expected behavior?
The Codex VS Code extension should not recursively allocate hundreds of thousands or more than one million inotify watches in the extension host for a workspace where VS Code's own file watcher is correctly constrained by files.watcherExclude.
Expected behavior:
- Respect VS Code workspace watcher excludes or apply equivalent filtering before recursive extension-side watching.
- Avoid recursively watching
.git/objectsand large generated/runtime directories. - Bound watcher allocation and degrade gracefully if a workspace is too large.
- Release extension-created watches when Codex chat tabs/panels are closed or when the triggering state ends.
- Avoid desktop-wide
ENOSPC/inotify exhaustion.
Additional information
The strongest isolation signal is process ownership:
normal VS Code file watcher: low watch count
Codex app-server child: about 213 watches
VS Code extension host: about 1,151,500 watches
A local mitigation confirmed that real workspace tree size drives the spike. Moving logs/ outside the real workspace tree and symlinking it back removed about 731k watches:
Before: Codex extension host about 1,151,522 watches
After moving logs/ out of the real tree: Codex extension host about 420,306 watches
That mitigation is only a workaround. It also shows that the extension host appears to expand the real filesystem tree under the workspace root instead of honoring the configured VS Code watcher excludes.
Closest related issue I found: openai/codex#23191 reports the same general git-repo-watcher/ENOSPC family in Cursor Remote SSH when $HOME accidentally becomes a large Git repo. This issue is separate because it reproduces in VS Code with an intended repo workspace, measured extension-host watch ownership, and normal VS Code watcher excludes already in place.
Adjacent but not identical: openai/codex#22421, openai/codex#17394, openai/codex#20295.
12 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I can reproduce the same watcher-exhaustion class on a newer Codex VS Code extension build. Sharing sanitized measurements in case they help with prioritization and fixing the extension-side watcher path.
Environment:
openai.chatgpt-26.616.51431-linux-x64fs.inotify.max_user_watches=1048576,fs.inotify.max_user_instances=2048Current process attribution after a full VS Code restart and local cleanup:
Most of the extensionHost watches map back to ignored/generated workspace trees:
Those high-churn/generated directories are already excluded from VS Code's normal watcher/search configuration, and the normal VS Code fileWatcher process remains comparatively small. The large count is owned by the extension host, which makes this look like the Codex extension-side watcher is still recursively watching large workspace subtrees instead of honoring VS Code
files.watcherExclude/ equivalent ignore rules before allocating watches.Impact observed before mitigation:
ENOSPC: System limit for number of file watchers reached.Expected behavior / likely useful fixes:
files.watcherExcludeand/or.gitignorefor the extension-side recursive watcher before watch allocation.node_modules,.next, mobile build outputs, local cache/artifact folders, and nested worktrees by default.No private logs attached here; the data above is sanitized process/count attribution only.
I can also reproduce this on openai.chatgpt-26.616.51431-linux-x64.
In my case, the large generated tree was
cdk.out. It had grown very large and contained many build asset files.Environment:
openai.chatgpt-26.616.51431-linux-x64fs.inotify.max_user_watches = 524288cdk.outVS Code had
files.watcherExcludeconfigured for**/cdk.out/**.Codex investigated
/proc/<pid>/fdinfoand mapped the inotify inode values back to workspace-relative paths.With the Codex VS Code extension enabled:
cdk.outcdk.out, so the VS Code watcher exclude was effective thereAfter disabling the Codex VS Code extension and reloading:
Temporarily, disabling the Codex VS Code extension is currently an effective workaround for my environment.
This also affects me. I'm disabling and deleting the Codex extension for now.
I hit this with the VS Code Codex extension on Linux. The failure appears related to the extension using:
On Linux, that recursive watch path can fail or exhaust inotify watcher limits on larger workspaces. A proper patch would be to use the VS Code file watch API.
A temporary local workaround is to intercept only recursive Linux fs.watch calls before loading the real extension bundle, and route them through VS Code’s watcher API instead:
Create
~/.vscode/extensions/openai.chatgpt-26.623.70822-linux-x64/wrapper.jsin
package.jsonfor the extension replacewith the wrapper
Quick one liner to check if the problem has gone away, run in root shell
before
after
I’m seeing what appears to be the same issue on a newer VS Code Codex extension build.
Environment:
openai.chatgpt-26.623.70822-linux-x64/home/.../image_generator/mnt/cimage_jobs/The generated output included render job files, plan JSON files, and rendered PNG frames. These directories were already excluded from the normal project/file-watcher paths:
image_jobs/was in.gitignore.vscode/settings.jsonhadfiles.watcherExcludefor**/image_jobs/**.vscode/settings.jsonhadsearch.excludefor**/image_jobs/**Observed behavior:
gpu_scheduler.py: about1.4-1.5%CPUrun_web.py: about1.0-1.1%CPUextensionHost:82-83%CPU1%CPU.The VS Code remote
extensionHostprocess held about463,303inotify watches, while the WSL inotify watch limit was524,288. So the extension host was close to exhausting the Linux file-watch limit.The Codex extension logs repeatedly showed:
Today: 357,817 inotify watches.
Adding another data point from a WSL / VS Code Server workspace that matches this issue closely.
Environment:
openai.chatgpt-26.5623.101652-linux-x64/home/kyle/projects/finance_toolkit**/.worktrees/**,**/.git/objects/**,**/node_modules/**,**/.cache/**,**/.tmp/**,**/.harness/**, etc. viafiles.watcherExcludeandsearch.exclude.fs.inotify.max_user_watches=1048576,fs.inotify.max_user_instances=8192.Relevant extension log lines show the extension-private watcher path, not just VS Code core file watching:
The key behavior is that the Codex extension git repo watcher appears to recurse into paths that users would reasonably expect to be ignored for watcher purposes:
.worktrees,.git/worktrees,.harness, nested cache directories, and generated test harness output. In this workspace,.worktreescontains agent-created git worktrees with their own dependencies and harness artifacts, so this can exhaust the watch budget even when VS Code core excludes are configured.The most practical workaround we have identified is to move future git worktrees outside the opened VS Code workspace root, for example from:
to a sibling root such as:
Raising the inotify limits helps temporarily, but it does not address the underlying issue that extension-private watching does not appear to honor the normal workspace exclude configuration. An extension-level watcher exclude setting, or default ignores for
.git,.worktrees,node_modules,.cache,.tmp, and.harness, would likely fix this class of workspace.I have the same issue. I asked codex to patch itself and it found:
The extension directly calls fs.watch() with recursive watching enabled, bypassing VS Code watcher exclusions. Changing the bundled expression from:
Kr.default.watch(i,{recursive:e.recursive}to:
Kr.default.watch(i,{recursive:false}stops the excessive watcher growth after reloading VS Code. Extension updates restore the original behavior.
But read-only debugging showed Vite was not the process consuming the watches.
Watcher ownership:
Sample watched paths owned by the Codex Desktop Electron process resolved to ignored/generated directories inside another worktree:
The Codex Desktop log also directly shows the git repo watcher trying to watch
node_modules:The repo already ignores these directories:
And Vite itself appears to ignore
**/.git/**and**/node_modules/**by default, so the Vite error was collateral damage: Codex Desktop had already consumed nearly the whole per-user inotify budget.This reproduced after a fresh system restart, so it does not appear to be stale pre-reboot processes. It appears to be recreated by Codex Desktop’s watcher after opening/resuming sessions.
Local conclusion:
git-repo-watcherappears to recursively watch ignored/generated dependency trees such asfrontend/node_modules.node_modulesfiles is enough to exhaust the user watch budget.vite.config.ts.Suggested fix direction:
node_modules,dist,storybook-static,.venv, cache/build artifact directories, and probably most.gitinternals from Codex Desktop recursive watchers..gitignoreor equivalent workspace excludes before allocating recursive watches.Independent reproduction on VS Code Remote SSH with Codex IDE extension 26.707.41301.
Sanitized observations:
files.watcherExcluderules were already configured for generated and log trees, but they did not constrain the Codexgit-repo-watcherbehavior.fs.inotify.max_user_watchesfrom 524288 to 2097152 did not reliably restore the panel, so increasing the kernel limit is not a durable fix.This appears consistent with the extension-side watcher bypassing VS Code watcher exclusions. Please consider:
files.watcherExcludeor equivalent filtering togit-repo-watcher.No code, repository contents, file paths, host addresses, usernames, attachments, or raw logs are included in this report.
Additional Dev Container reproduction:
Codex.log reports:
[git-repo-watcher] ENOSPC: System limit for number of file watchers reached
The remote extension host then reaches about 2041 MB V8 heap and crashes:
FATAL ERROR: JavaScript heap out of memory
Extension Host Process exited with signal SIGABRT
Docker/cgroup OOM is ruled out:
OOMKilled=false
memory.events: oom=0, oom_kill=0
files.watcherExclude does not appear to constrain the Codex watcher.