Skip to content

Instantly share code, notes, and snippets.

@akihikodaki
Created June 26, 2026 10:13
Show Gist options
  • Select an option

  • Save akihikodaki/cfe1e0af7ea7400d1828832ce858d7da to your computer and use it in GitHub Desktop.

Select an option

Save akihikodaki/cfe1e0af7ea7400d1828832ce858d7da to your computer and use it in GitHub Desktop.

Codex VS Code Extension Loading Findings

Summary

The Codex VS Code panel was stuck loading while the remote extension host was repeatedly reconnected instead of replaced. Two separate issues were found:

  • The installed Codex extension bundle hit a Node compatibility path involving the global navigator object.
  • Codex's internal GitRepoWatcher requested a recursive watch on the repository root, separate from VS Code's files.watcherExclude.

The VS Code workspace watcher exclusion for obj is in place, but it does not configure Codex's internal Git watcher.

Environment

  • Workspace: /home/odaki/dlp/b
  • Installed extension: openai.chatgpt-26.616.81150-linux-x64
  • Installed extension path: /home/odaki/dlp/b/obj/home/.vscode-server/extensions/openai.chatgpt-26.616.81150-linux-x64
  • Bundled Codex CLI version: codex-cli 0.142.0
  • VS Code Server Node version: v24.15.0

VS Code Watcher Exclusion

The tracked workspace setting was changed to recursive globs:

"files.watcherExclude": {
  "**/gem5/**": true,
  "**/obj/**": true,
  "**/riscv-gnu-toolchain/**": true,
  "**/snipersim/**": true
}

This affects VS Code's file watcher configuration. It does not affect Codex's internal Git watcher.

Codex GitRepoWatcher

The installed extension bundle contains a GitRepoWatcher implementation that watches Git metadata and the working tree.

The metadata watchers cover paths such as:

  • HEAD
  • index
  • FETCH_HEAD
  • packed-refs
  • the synced branch reference

The working tree watcher requested a recursive watch on the repository root:

await this.tryWatchDirectory(
  this.options.root,
  "working-tree",
  this.emitWorkingTreeChangedDebounced,
  s => !this.isGitInternalPath(e, s)
)

For the local host, the underlying watch implementation uses Node's filesystem watcher:

fs.watch(path, { recursive: e.recursive }, ...)

No exclusion list is passed into that call.

Codex does later filter changed paths through Git ignore checks, but that happens after watch events are received. Because /obj is ignored by Git, event processing can filter it, but the initial recursive root watch is still requested.

Configuration Surface

The installed extension's declared VS Code settings are:

  • chatgpt.commentCodeLensEnabled
  • chatgpt.cliExecutable
  • chatgpt.openOnStartup
  • chatgpt.followUpQueueMode
  • chatgpt.composerEnterBehavior
  • chatgpt.reviewDelivery
  • chatgpt.localeOverride
  • chatgpt.runCodexInWindowsSubsystemForLinux

No setting was found for:

  • Git watcher exclusions
  • working-tree watcher disablement
  • mapping files.watcherExclude into Codex's internal watcher

No supported GitRepoWatcher exclusion knob was found in the installed package.

Local Patches Applied

The installed extension was patched under obj/home/.vscode-server/extensions. These edits are local to the installed extension copy and may be overwritten by an extension update or reinstall.

Navigator Compatibility Patch

The extension bundle was patched to avoid direct navigator detection paths that failed under VS Code Server Node.

Verification after the patch:

  • No typeof navigator<"u" occurrences remained.
  • Three false&&navigator guard remnants remained.
  • node --check passed for the patched bundle.

Working-Tree Watcher Patch

The recursive working-tree watch call was removed from the installed minified bundle.

After patching:

  • tryWatchDirectory(this.options.root,"working-tree" occurrences: 0
  • Git metadata watchers remain in the bundle.
  • node --check passed for the patched bundle.

Expected tradeoff: Codex may not live-refresh some working-tree state purely from filesystem events. Explicit Git/status/apply/commit operations should still query Git directly.

Process Evidence

Before restarting the extension host, the live process state showed:

  • VS Code extension host PID 452: D (disk sleep)
  • Codex app-server PID 508: S (sleeping)

The remote agent log also showed repeated reconnections to the same extension host because VSCODE_RECONNECTION_GRACE_TIME was 10800000ms (10800s).

After terminating the stuck extension host and app-server, VS Code started:

  • VS Code extension host PID 3675: S (sleeping)
  • Codex app-server PID 3700: S (sleeping)

The fresh Codex log got past the earlier stall point after:

[git-repo-watcher] Starting git repo watcher

and continued with later Git activity.

Remaining Warnings

The fresh Codex log still contains warnings that do not appear to be the panel-loading blocker:

  • bundled bubblewrap fallback because bubblewrap is not on PATH
  • invalid or unknown experimental feature keys
  • plugin manifest default prompt length warning for ngs-analysis
  • a nonzero Git command while probing refs/remotes/origin/HEAD

Verification

The patched extension bundle passed syntax checking:

/vscode/vscode-server/bin/linux-x64/7e7950df89d055b5a378379db9ee14290772148a/node --check \
  /home/odaki/dlp/b/obj/home/.vscode-server/extensions/openai.chatgpt-26.616.81150-linux-x64/out/extension.js

Repository validation passed:

make -j$(nproc) lint obj/site

The validation completed with MkDocs, Biome, Ruff, and Pyrefly passing.

Follow-Up Options

  • Keep the local extension bundle patch as a diagnostic workaround.
  • Reapply the patch after extension updates if the issue returns.
  • Ask upstream for a supported GitRepoWatcher exclusion or a setting to disable the recursive working-tree watcher.
  • Consider reducing VS Code's extension-host reconnection grace time in the devcontainer if reloads keep reconnecting to stuck hosts.
@akihikodaki

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment