VS Code Codex extension can allocate about 1M inotify watches on Linux large workspace

Open 💬 12 comments Opened May 19, 2026 by interconnectedMe
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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?

  1. On Linux, open a large VS Code workspace with the Codex extension enabled.
  2. 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
  1. Configure VS Code workspace excludes for those large directories, for example:
"files.watcherExclude": {
  "**/.sandcastle/worktrees/**": true,
  "**/data/**": true,
  "**/logs/**": true
}
  1. 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.
  2. 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/objects and 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.

View original on GitHub ↗

12 Comments

github-actions[bot] contributor · 2 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #23191

Powered by Codex Action

crystal150 · 29 days ago

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:

  • IDE: VS Code Remote SSH, VS Code 1.125.1
  • OS: Ubuntu 22.04.5 LTS, Linux 5.15 x86_64
  • Codex IDE extension: openai.chatgpt-26.616.51431-linux-x64
  • Current inotify limits after local mitigation: fs.inotify.max_user_watches=1048576, fs.inotify.max_user_instances=2048

Current process attribution after a full VS Code restart and local cleanup:

VS Code extensionHost:        357,182 inotify watches
VS Code fileWatcher process:   14,455 inotify watches
Codex app-server child:         1,650 inotify watches
total user watches:           382,095

Most of the extensionHost watches map back to ignored/generated workspace trees:

node_modules:                    253,381
apps/mobile/build:                32,233
.claude/worktrees:                19,061
other workspace files:            17,106
.agents/skills/.../.local:        11,230
.git:                              7,923
.local:                            7,400
apps/web/.next:                    4,764
.playwright-cli:                   4,081

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:

  • Remote Extension Host logs showed ENOSPC: System limit for number of file watchers reached.
  • VS Code became unstable/hung when Codex IDE extension was active alongside another AI coding extension.
  • The other extension was not the main watcher owner in the measured state; Codex/VS Code extensionHost dominated the inotify count.
  • Raising the OS inotify limit and killing a stale extensionHost process made the workspace usable again, but that is only a workaround.

Expected behavior / likely useful fixes:

  • Honor VS Code files.watcherExclude and/or .gitignore for the extension-side recursive watcher before watch allocation.
  • Add an extension-specific watcher exclude setting if the watcher cannot rely on VS Code settings.
  • Avoid watching generated dependency/build trees like node_modules, .next, mobile build outputs, local cache/artifact folders, and nested worktrees by default.
  • Bound watcher allocation and degrade gracefully before exhausting the user's inotify budget.

No private logs attached here; the data above is sanitized process/count attribution only.

pinelibg · 28 days ago

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:

  • VS Code Server: 1.125.1
  • Codex extension: openai.chatgpt-26.616.51431-linux-x64
  • OS: Ubuntu 24.04 x86_64
  • Effective sysctl value: fs.inotify.max_user_watches = 524288
  • Workspace: large monorepo with very large generated cdk.out

VS Code had files.watcherExclude configured for **/cdk.out/**.

Codex investigated /proc/<pid>/fdinfo and mapped the inotify inode values back to workspace-relative paths.

With the Codex VS Code extension enabled:

  • VS Code extensionHost: 508,479 watches
  • VS Code fileWatcher: 15,623 watches
  • Of the extensionHost watches, 501,622 mapped to cdk.out
  • The normal VS Code fileWatcher had 0 watches for cdk.out, so the VS Code watcher exclude was effective there

After disabling the Codex VS Code extension and reloading:

  • VS Code extensionHost dropped from 508,479 watches to 1 watch
  • VS Code fileWatcher remained around 15,623 watches

Temporarily, disabling the Codex VS Code extension is currently an effective workaround for my environment.

tomasruizt · 26 days ago

This also affects me. I'm disabling and deleting the Codex extension for now.

Pascu-Victor · 21 days ago

I hit this with the VS Code Codex extension on Linux. The failure appears related to the extension using:

  fs.watch(path, { recursive: true }, listener)

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.js

"use strict";

const fs = require("node:fs");
const path = require("node:path");
const { EventEmitter } = require("node:events");

const originalWatch = fs.watch.bind(fs);

function shouldUseVsCodeWatcher(options) {
  return process.platform === "linux" && options?.recursive === true;
}

function createVsCodeRecursiveWatcher(root, listener) {
  const watcher = new EventEmitter();
  const vscode = require("vscode");
  const pattern = new vscode.RelativePattern(vscode.Uri.file(root), "**/*");
  const fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);

  const emitChange = (eventType, uri) => {
    const relativePath = path.relative(root, uri.fsPath);
    listener?.(eventType, relativePath || path.basename(uri.fsPath));
  };

  fileWatcher.onDidCreate((uri) => emitChange("rename", uri));
  fileWatcher.onDidDelete((uri) => emitChange("rename", uri));
  fileWatcher.onDidChange((uri) => emitChange("change", uri));

  watcher.close = () => {
    fileWatcher.dispose();
  };

  return watcher;
}

fs.watch = function patchedWatch(filename, options, listener) {
  if (typeof options === "function") {
    listener = options;
    options = undefined;
  }

  if (shouldUseVsCodeWatcher(options)) {
    try {
      return createVsCodeRecursiveWatcher(path.resolve(String(filename)), listener);
    } catch {
      return originalWatch(filename, { ...options, recursive: false }, listener);
    }
  }

  return originalWatch(filename, options, listener);
};

module.exports = require("./extension.js");

in package.json for the extension replace

  "main": "./out/extension.js",

with the wrapper

  "main": "./out/wrapper.js",

Quick one liner to check if the problem has gone away, run in root shell

find /proc/*/fd/ -type l -lname "anon_inode:inotify" -printf "%hinfo/%f\n" | xargs grep -cE "^inotify" | sort -nk2 -t: | sed -E 's/:([0-9]+)$/\t\t\1/' | tail -10

before

/proc/1048513/fdinfo/44   46
/proc/2613/fdinfo/18      49
/proc/3148/fdinfo/14      62
/proc/1974/fdinfo/537     112
/proc/2267/fdinfo/7       134
/proc/1/fdinfo/7          150
/proc/1974/fdinfo/532     191
/proc/1048513/fdinfo/47   38085 <- vscode file watch process
/proc/1048455/fdinfo/104  458280 <- vscode extension host eating 450K inotify watches!

after

/proc/3977877/fdinfo/31         30
/proc/3990348/fdinfo/30         31
/proc/517243/fdinfo/31          31
/proc/2734/fdinfo/15            49
/proc/3173/fdinfo/14            62
/proc/1992/fdinfo/521           117
/proc/2462/fdinfo/7             135
/proc/1/fdinfo/7                152
/proc/1992/fdinfo/528           206
/proc/3990300/fdinfo/47         40681  <- vscode  file watch process
russpatterson · 19 days ago

I’m seeing what appears to be the same issue on a newer VS Code Codex extension build.

Environment:

  • VS Code Remote WSL
  • Codex extension: openai.chatgpt-26.623.70822-linux-x64
  • Workspace is under WSL Linux home: /home/.../image_generator
  • Workspace is not under /mnt/c
  • The repo had high-churn generated image-rendering output under image_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.json had files.watcherExclude for **/image_jobs/**
  • .vscode/settings.json had search.exclude for **/image_jobs/**

Observed behavior:

  • The machine became sluggish while image rendering jobs were running.
  • The render/scheduler processes were not the CPU hog:
  • gpu_scheduler.py: about 1.4-1.5% CPU
  • run_web.py: about 1.0-1.1% CPU
  • The hot process was the VS Code remote extensionHost:
  • sustained around 82-83% CPU
  • CPU was concentrated on the extension host main Node thread
  • The Codex app-server child was only around 1% CPU.

The VS Code remote extensionHost process held about 463,303 inotify watches, while the WSL inotify watch limit was 524,288. So the extension host was close to exhausting the Linux file-watch limit.

The Codex extension logs repeatedly showed:

[git-repo-watcher] Git repo watcher failed errorCode=ENOSPC
ENOSPC: System limit for number of file watchers reached
The failed watch paths included generated image output and git internals, for example:
/home/.../image_generator/image_jobs/.../rendered_frames/R_...png
/home/.../image_generator/image_jobs/.../plans/P_...json
/home/.../image_generator/.git/objects/...
Stopping the GPU scheduler improved the symptom only because it stopped creating new files under image_jobs/. The CPU load itself appeared to come from the Codex extension-side watcher reacting to those generated files, not from the render process.
To make the machine usable again, I had to move the image rendering job, plan, and rendered-output directories out of the real repo tree so Codex would stop recursively watching them. That reduced the responsiveness problem, but it is only a workaround.
This seems to confirm that the Codex extension-side watcher is bypassing VS Code’s normal watcher excludes and/or .gitignore, recursively watching high-churn generated output and .git/objects, then driving extensionHost CPU and inotify pressure.
interconnectedMe · 19 days ago

Today: 357,817 inotify watches.

### 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? 1. On Linux, open a large VS Code workspace with the Codex extension enabled. 2. 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 ` 3. Configure VS Code workspace excludes for those large directories, for example: "files.watcherExclude": { "**/.sandcastle/worktrees/**": true, "**/data/**": true, "**/logs/**": true } 4. 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. 5. 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/objects and 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: [#23191](https://github.com/openai/codex/issues/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: #22421, #17394, #20295.
kyle3728 · 14 days ago

Adding another data point from a WSL / VS Code Server workspace that matches this issue closely.

Environment:

  • Extension: openai.chatgpt-26.5623.101652-linux-x64
  • Host: VS Code Server in WSL
  • Workspace root: a large repo at /home/kyle/projects/finance_toolkit
  • Existing workspace settings already exclude **/.worktrees/**, **/.git/objects/**, **/node_modules/**, **/.cache/**, **/.tmp/**, **/.harness/**, etc. via files.watcherExclude and search.exclude.
  • Kernel limits at the time were already relatively high: 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:

2026-07-03 01:07:02.193 [info] [git-repo-watcher] Starting git repo watcher
2026-07-03 10:15:50.217 [warning] [git-repo-watcher] Git repo watcher failed errorCode=ENOSPC errorMessage="ENOSPC: System limit for number of file watchers reached, watch `/home/kyle/projects/finance_toolkit/.worktrees/harness-golden-usage-closeout/.tmp-harness-golden-symlink-target`" path=/home/kyle/projects/finance_toolkit
2026-07-03 10:18:10.270 [warning] [git-repo-watcher] Git repo watcher failed errorCode=ENOSPC errorMessage="ENOSPC: System limit for number of file watchers reached, watch `/home/kyle/projects/finance_toolkit/.worktrees/harness-golden-usage-closeout/.cache/test-harness/docker-config/buildx`" path=/home/kyle/projects/finance_toolkit
2026-07-03 10:26:02.993 [warning] [git-repo-watcher] Git repo watcher failed errorCode=ENOSPC errorMessage="ENOSPC: System limit for number of file watchers reached, watch `/home/kyle/projects/finance_toolkit/.git/worktrees/harness-golden-usage-closeout/index.lock`" path=/home/kyle/projects/finance_toolkit
2026-07-03 10:31:24.006 [warning] [git-repo-watcher] Git repo watcher failed errorCode=ENOSPC errorMessage="ENOSPC: System limit for number of file watchers reached, watch `/home/kyle/projects/finance_toolkit/.worktrees/harness-golden-usage-closeout/.harness/review`" path=/home/kyle/projects/finance_toolkit

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, .worktrees contains 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:

/home/kyle/projects/finance_toolkit/.worktrees/<name>

to a sibling root such as:

/home/kyle/projects/finance_toolkit-worktrees/<name>

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.

rfunderburk · 13 days ago

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.

zuuxuux · 12 days ago
I’m seeing what looks like the same bug family in Codex Desktop on Linux.

Environment:
- Codex Desktop process: `/opt/codex-desktop/electron`
- OS: Linux desktop
- Repo type: Vite/React app with `frontend/node_modules` present
- Kernel limits:
  - `fs.inotify.max_user_watches = 65536`
  - `fs.inotify.max_user_instances = 128`

Observed failure:
- Running the repo’s normal startup eventually failed in Vite with:

```text
Error: ENOSPC: System limit for number of file watchers reached, watch '/home/<user>/code/<repo>/frontend/vite.config.ts'

But read-only debugging showed Vite was not the process consuming the watches.

Watcher ownership:

visible_inotify_watches=65582
visible_inotify_instances=96

64676 watches  PID <pid>  /opt/codex-desktop/electron ...
271 watches    PID <pid>  .../codex app-server ...
0 watches      PID <pid>  node /home/<user>/code/<other-worktree>/frontend/node_modules/.bin/vite ...

Sample watched paths owned by the Codex Desktop Electron process resolved to ignored/generated directories inside another worktree:

/home/<user>/code/<other-worktree>/frontend/node_modules/@firebase/auth/dist/esm2017/src/index.d.ts
/home/<user>/code/<other-worktree>/frontend/node_modules/@firebase/auth/dist/esm2017/src/core/util/browser.d.ts
/home/<user>/code/<other-worktree>/frontend/node_modules/@firebase/auth/dist/esm2017/src/mfa/index.d.ts
/home/<user>/code/<other-worktree>/.git/refs/heads/...
/home/<user>/code/<other-worktree>/.agents/skills/...

The Codex Desktop log also directly shows the git repo watcher trying to watch node_modules:

[git-repo-watcher] Git repo watcher failed errorCode=ENOSPC
errorMessage="ENOSPC: System limit for number of file watchers reached, watch '/home/<user>/code/<other-worktree>/frontend/node_modules/@firebase/auth/dist/node-esm/index.js'"
path=/home/<user>/code/<other-worktree>

The repo already ignores these directories:

frontend/node_modules/
frontend/dist/
frontend/storybook-static/

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:

  • Codex Desktop’s git-repo-watcher appears to recursively watch ignored/generated dependency trees such as frontend/node_modules.
  • On Linux default inotify limits, one worktree with ~77k node_modules files is enough to exhaust the user watch budget.
  • The downstream symptom can appear in unrelated tools, e.g. Vite failing to watch vite.config.ts.

Suggested fix direction:

  • Exclude node_modules, dist, storybook-static, .venv, cache/build artifact directories, and probably most .git internals from Codex Desktop recursive watchers.
  • Respect .gitignore or equivalent workspace excludes before allocating recursive watches.
  • Add bounds/backoff/degraded polling behavior when watcher allocation approaches or hits ENOSPC.
  • Surface a clear warning naming the owning Codex watcher and path, rather than allowing unrelated tools to fail later.
jinyuliao · 8 days ago

Independent reproduction on VS Code Remote SSH with Codex IDE extension 26.707.41301.

Sanitized observations:

  • The workspace contained approximately 788k files and 70k directories; a generated build subtree accounted for approximately 385k files and 34k directories.
  • VS Code files.watcherExclude rules were already configured for generated and log trees, but they did not constrain the Codex git-repo-watcher behavior.
  • Under inotify pressure, the Codex panel stopped appearing reliably.
  • Temporarily raising fs.inotify.max_user_watches from 524288 to 2097152 did not reliably restore the panel, so increasing the kernel limit is not a durable fix.
  • Reload cycles produced multiple extension-host/workspace-lock activity, which may compound watcher allocation.
  • Disabling Codex only for this large workspace removed the immediate trigger; the system watch limit was then restored to 524288.

This appears consistent with the extension-side watcher bypassing VS Code watcher exclusions. Please consider:

  1. Applying files.watcherExclude or equivalent filtering to git-repo-watcher.
  2. Avoiding recursive watches of generated trees and Git object storage.
  3. Bounding watcher allocation and degrading gracefully.
  4. Deduplicating and releasing watches across extension-host reloads.

No code, repository contents, file paths, host addresses, usernames, attachments, or raw logs are included in this report.

LewisLyx · 4 days ago

Additional Dev Container reproduction:

  • Extension: openai.chatgpt-26.5707.91948-linux-x64
  • VS Code Server commit: 125df4672b8a6a34975303c6b0baa124e560a4f7
  • Workspace output tree: 28 GB
  • .git directory: 6.5 GB
  • fs.inotify.max_user_watches: 1048576

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.