Windows Desktop 26.810.4967.0: browser extension install banner repeatedly spawns `reg.exe` and burns CPU while idle

Open 💬 2 comments Opened Aug 14, 2026 by wunacks-creator

Reporter: @wunacks-creator

Summary

On Windows 11, the ChatGPT/Codex desktop main process entered a sustained high-CPU loop while no local Codex task was doing meaningful work.

ETW process tracing showed that the Electron main process spawned C:\Windows\System32\reg.exe approximately once every 0.7–0.8 seconds. Static inspection of the packaged desktop JavaScript linked this process creation to the browser-extension install-banner path, which queries the Windows default HTTPS browser using:

reg.exe query HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice /v ProgId

The returned ProgId was ChromeHTML.

The ChatGPT Chrome extension was already installed, and no actionable install banner was visible. The persisted atom browserExtensionInstallBannerDismissed was absent, so the install-banner query remained eligible. Persisting that atom as true and restarting the app stopped the loop completely.

Environment

  • ChatGPT/Codex Desktop: 26.810.4967.0 x64
  • Windows: Windows 11 Pro 10.0.26100, build 26100, x64
  • Logical processors: 16
  • Physical memory: approximately 31.6 GiB
  • Default HTTPS handler: ChromeHTML
  • Google Chrome product version observed by the desktop runtime: 151.0.7922.137
  • Installed ChatGPT Chrome extension:
  • Name: ChatGPT
  • Version: 1.2.27259.19709
  • Extension ID: hehggadaopoacecdllhhajmbjkdcmajg
  • Bundled Chrome plugin: chrome@openai-bundled, version 26.810.41047

Observed behavior before mitigation

The sustained hot process was the top-level ChatGPT.exe Electron main process. Renderer, GPU, Codex app-server, code-mode host, and plugin child processes were mostly idle.

Repeated samples showed:

  • Main-process CPU: approximately 1.4–2.1 core equivalents
  • Main-process share of whole-machine CPU: approximately 8.75–13.02% on 16 logical processors
  • ChatGPT process-group working set: approximately 2.2 GiB
  • Main-process I/O read-transfer counter: approximately 900–930 MiB/s
  • Main-process read operations: approximately 1,850–1,880 operations/s

The read-transfer number is the Windows process I/O counter and may include cached reads; Task Manager did not show equivalent physical-disk throughput.

In a 10-second Microsoft-Windows-Kernel-Process ETW capture:

Parent process: ChatGPT.exe
Child image: C:\Windows\System32\reg.exe
Observed starts: 13
Interval: approximately 0.67–0.79 seconds

Each short-lived reg.exe also created a short-lived console host.

A separate kernel file trace showed the main process repeatedly touching bundled plugin/runtime paths, including the bundled Chrome plugin and extension ID metadata, during the same loop.

Relevant desktop code path

Static inspection of the packaged desktop app found:

  • getExtensionInstallBanner() calls the default-browser resolver.
  • On Windows, the resolver executes the reg.exe query ... UserChoice /v ProgId command shown above.
  • The renderer query key is chromium-browser-extension-install-banner.
  • It is configured with refetchOnMount: "always" and refetchOnWindowFocus: "always", with a one-minute stale time.
  • The query is enabled while the persisted browserExtensionInstallBannerDismissed atom is false/absent and the banner is otherwise eligible.

The observed 0.7–0.8 second process cadence suggests the banner/query component was repeatedly remounted or otherwise refetched despite the stale time. The exact UI invalidation trigger was not determined, but the external process creation was directly observed and the query path was isolated through the controlled mitigation below.

Reproduction

  1. On Windows, install and enable the bundled Chrome plugin and ChatGPT Chrome extension.
  2. Use a profile where electron-persisted-atom-state.browserExtensionInstallBannerDismissed is absent or false.
  3. Launch ChatGPT/Codex Desktop 26.810.4967.0.
  4. Leave the desktop app open with no meaningful local workload.
  5. Observe the top-level ChatGPT.exe process consuming sustained CPU.
  6. Capture process-start ETW events for the main process.
  7. Observe repeated reg.exe children querying the default HTTPS browser.

Simply quitting and reopening the app did not resolve the problem because the persisted banner-dismissed state remained absent.

Controlled mitigation and verification

The global state file was backed up. Only this persisted atom was changed:

{
  "electron-persisted-atom-state": {
    "browserExtensionInstallBannerDismissed": true
  }
}

After fully restarting the desktop app, two independent samples showed:

Main-process CPU:             0.012–0.022 core equivalents
Whole-machine CPU share:     0.07–0.14%
I/O read-transfer rate:      0.0 MiB/s
Read operations:             0.6–2.5 operations/s
Main-process private bytes:  approximately 222–227 MiB
Process-group working set:   approximately 1.20 GiB

In a fresh 10-second kernel process trace after the restart:

Child processes started by ChatGPT.exe: 0
reg.exe starts from any parent:         0

The Chrome extension and chrome@openai-bundled plugin remained installed and available. The mitigation disabled only the install-banner query.

Expected behavior

  • An already-installed compatible ChatGPT browser extension should not leave the install-banner query running indefinitely.
  • Default-browser detection should be cached and should not spawn an external process on repeated component mounts or focus events.
  • Query invalidation/remount behavior should be bounded and respect the stale time.
  • A hidden or non-actionable banner must not generate sustained background CPU and I/O activity.

Actual behavior

  • The install-banner query remained eligible because the dismissal atom was absent.
  • The desktop main process repeatedly executed reg.exe approximately 13 times per 10 seconds.
  • CPU, process I/O, and memory usage remained elevated while the app appeared idle.
  • A normal app restart did not clear the loop.

Suggested fix directions

  1. Treat an already-installed compatible extension as a terminal state for the install banner.
  2. Cache Windows default-browser resolution and avoid reg.exe for every query evaluation.
  3. Deduplicate in-flight/default-browser queries across renderer windows.
  4. Investigate why chromium-browser-extension-install-banner is remounted or refetched every 0.7–0.8 seconds despite its one-minute stale time.
  5. Add a regression test asserting that an idle desktop instance creates no repeated reg.exe children.

Privacy

  • No authentication token, cookie, email address, ChatGPT account ID, installation ID, browser history, Chrome profile data, prompt content, or local project path is included.
  • No auth.json content was read or attached.
  • Local user paths are omitted or represented generically.
  • The GitHub issue itself will identify the reporter through the connected GitHub account.

View original on GitHub ↗

2 Comments

wunacks-creator · 14 days ago

Update / correction: the earlier restart-based mitigation was not durable. The loop has recurred in the same app session, and I can now reproduce it reliably on Windows Desktop 26.810.4967.0.

New evidence:

  • A 10-second process ETW trace captured 12 launches of reg.exe, roughly one every 0.7-0.9 seconds, all parented by the main ChatGPT.exe process.
  • The repeated command is:

reg.exe query HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice /v ProgId

  • The default browser resolves successfully to ChromeHTML; the Chrome extension is already installed.
  • The persisted setting is already correct on disk:

electron-persisted-atom-state.browserExtensionInstallBannerDismissed = true
in both .codex-global-state.json and its backup.

  • Reloading each renderer separately did not stop the loop. Terminating all current renderer processes simultaneously also did not stop it; the main process recreated them and the loop resumed immediately.
  • A 15-second sample after the simultaneous renderer reload still showed:
  • 1.346 CPU cores consumed by the main process
  • 833.78 MB/s process read throughput
  • 1757.4 read operations/s
  • about 2.09 GB private bytes across the ChatGPT process group
  • Even the app's own read-only screen-context request timed out repeatedly while the loop was active.

The packaged renderer code enables the query only when its in-memory value for browserExtensionInstallBannerDismissed is exactly false, while the persisted host state is already true. This points to a renderer persisted-atom/state-sync or repeated-mount bug rather than a malformed Windows default-browser association.

There is no documented user-facing switch to disable this banner query, and no newer package was available from the configured winget sources at the time of testing. A remote feature-gate kill switch or a build that prevents repeated execution of getExtensionInstallBanner() would be appreciated. Please treat the issue as still reproducible; restart/priority changes are not a fix.

skb-oai · 13 days ago

Thank you for filing this issue @wunacks-creator! I will take a look and make sure a fix gets in ASAP