macOS: same-version Chrome plugin cache reconciliation deletes chrome/latest while the plugin remains current

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

What version of the Codex App are you using (From “About Codex” dialog)?

ChatGPT desktop app 26.730.61639 (build 6234, bundle identifier com.openai.codex).

The bundled chrome@openai-bundled plugin is also version 26.730.61639.

What subscription do you have?

ChatGPT Pro

What platform is your computer?

~~~text
Darwin 25.5.0 arm64 arm
Google Chrome 150.0.7871.188
ChatGPT Chrome Extension 1.2.27236.6274_0
~~~

What issue are you seeing?

On macOS, a same-version bundled-plugin cache reconciliation can replace the entire Chrome plugin cache root and delete the runtime-created latest symlink, even though the current versioned plugin directory remains complete and the plugin is still reported as installed, enabled, and current.

Before reconciliation:

~~~text
~/.codex/plugins/cache/openai-bundled/chrome/
├── 26.730.61639/
└── latest -> 26.730.61639
~~~

After reconciliation, without an app or plugin version change:

~~~text
~/.codex/plugins/cache/openai-bundled/chrome/
└── 26.730.61639/
~~~

The versioned directory still exists, but latest is absent. The plugin manager still reports:

~~~text
chrome@openai-bundled installed, enabled 26.730.61639
~~~

The Chrome Native Messaging manifest remains syntactically valid and continues to point through the missing alias:

~~~text
/Users/<user>/.codex/plugins/cache/openai-bundled/chrome/latest/extension-host/macos/arm64/ChatGPT for Chrome
~~~

Therefore, once latest is deleted, a fresh native-host launch resolves to a nonexistent path. This can be temporarily masked when the native host and its communication channel are already running: an existing connection may continue controlling Chrome without resolving the manifest again.

Manually recreating the current-version symlink restores a fresh Chrome connection:

~~~sh
cd ~/.codex/plugins/cache/openai-bundled/chrome
ln -s 26.730.61639 latest
~~~

After this repair, Codex successfully opened https://example.com/ in the user's Chrome and read the page title and heading. A later bundled-plugin cache rebuild deleted the manually repaired symlink again, so the workaround is not durable.

This leaves three layers inconsistent:

  1. The complete versioned plugin directory exists.
  2. The plugin manager reports the plugin installed/enabled/current.
  3. The Native Messaging manifest points through a missing latest alias.

What steps can reproduce the bug?

  1. Install and enable the bundled Chrome plugin and the ChatGPT Chrome Extension on macOS.
  2. Confirm that the cache contains both chrome/26.730.61639/ and chrome/latest -> 26.730.61639.
  3. Confirm that the Chrome Native Messaging manifest points to chrome/latest/.../ChatGPT for Chrome.
  4. Resume/switch desktop tasks or open the plugin UI and allow the bundled-plugin background reconciliation to run. In the observed runs, all bundled plugin version directories were recreated together without a version change. The desktop log does not emit a dedicated cache-swap event, so the exact initiating UI request is not yet proven.
  5. Inspect the cache again.
  6. Observe that chrome/26.730.61639/ remains complete, but chrome/latest has been deleted.
  7. Observe that the plugin still appears installed, enabled, and current.
  8. Recreate latest as a symlink to 26.730.61639 and establish a fresh Chrome connection. Chrome control works.
  9. Allow another bundled-plugin reconciliation to run.
  10. Observe that the manually repaired latest symlink is deleted again.

This was observed repeatedly on the same desktop/plugin version; no application upgrade occurred between deletion events.

What is the expected behavior?

Bundled-plugin reconciliation should preserve or atomically recreate every runtime artifact required by the installed plugin.

  • If Native Messaging manifests use chrome/latest, that alias should always point to the active complete plugin version.
  • A plugin should not be reported as current when its registered native-host executable does not resolve to an existing executable.
  • The versioned directory, active alias, Native Messaging manifest, and installed-plugin state should be reconciled as one recoverable transaction.
  • A manually repaired current-version alias should not be removed by a same-version background refresh.
  • Preferably, a long-lived native host should be registered from a stable location outside a replaceable plugin-cache root.

Additional information

Related but not duplicate
  • #31904 reports a dangling latest symlink that still points to a removed old plugin version, together with a stale executable name after an update.
  • #32238 primarily reports Chrome for Testing/Chromium selection and also notes an alias still pointing to an old removed version.
  • #32706 and #22114 report Windows file-lock/partial-update transaction failures.
  • #24296 describes the broader Windows architectural risk of running the native host from a mutable plugin cache.
  • #18863 covers symlinks inside plugin source trees being skipped during copying.

This report is specifically about macOS, standard Chrome, no version transition, and the latest sibling itself being deleted after a successful same-version plugin-root rebuild. The current version directory remains present and the plugin remains reported as current.

Possible source-level cause

This is a hypothesis based on the current public source, separate from the directly observed filesystem behavior:

The filesystem deletion, incorrect current status, manifest path, temporary symlink repair, successful Chrome control after repair, and repeated deletion were directly observed. The exact background caller that initiated the successful root replacement is inferred from the simultaneous bundled-plugin rebuild and current Store implementation.

All usernames, workspace paths, prompts, account data, private URLs, logs, and task/session identifiers have been omitted.

View original on GitHub ↗

8 Comments

github-actions[bot] contributor · 23 days ago

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

  • #36100

Powered by Codex Action

STSNaive · 23 days ago

Thanks — I reviewed #36100. It appears related, but it does not cover the failure reported here, so I am keeping this issue open.

The two reports affect different layers:

  • #36100: a content-variant mismatch repeatedly classifies same-version bundled plugins as outdated and reinstalls them. The reported impact is a 30–40 second startup delay.
  • #37059: after a same-version plugin-root replacement succeeds, the current version directory remains complete and the plugin remains installed, enabled, current, but the runtime-created sibling chrome/latest is absent. The Native Messaging manifest therefore resolves to a nonexistent host path. Recreating the symlink restores Chrome control, and a later reconciliation removes it again.

#36100's variant mismatch may be one trigger that causes the replacement path to run repeatedly. However, that would make it an upstream trigger for this report, not the same correctness bug. Fixing the unnecessary outdated classification would reduce how often this occurs, but any legitimate same-version replacement would still need to preserve or atomically recreate the runtime artifacts required by the Native Messaging registration.

The invariant specific to this issue is:

versioned cache exists and is current
+ Native Messaging manifest uses chrome/latest
+ successful root replacement omits chrome/latest
= installed/current state with a non-resolving registered host

For that reason, #36100 is related but not a duplicate of this issue.

c2keesey · 17 days ago

Confirming an independent reproduction on macOS with standard Google Chrome.

Environment

  • ChatGPT desktop app: 26.803.61601 (build 6396)
  • Bundled Chrome plugin: 26.803.61601
  • macOS: 26.5.2 arm64
  • Google Chrome: 151.0.7922.76
  • ChatGPT Chrome Extension: 1.2.27236.6274_0
  • Codex CLI: 0.147.0

Observed state

The cache contains only the complete versioned plugin directory:

~/.codex/plugins/cache/openai-bundled/chrome/26.803.61601/

There is no chrome/latest entry. Chrome's Native Messaging manifest still points to:

~/.codex/plugins/cache/openai-bundled/chrome/latest/extension-host/macos/arm64/ChatGPT for Chrome

That target does not exist, while the executable does exist and passes strict code-signature verification at:

~/.codex/plugins/cache/openai-bundled/chrome/26.803.61601/extension-host/macos/arm64/ChatGPT for Chrome

Browser discovery therefore returns:

Browser is not available: chrome

False-green diagnostic

check-native-host-manifest.js --browser chrome --json reports:

{
  "exists": true,
  "nameMatches": true,
  "missingExpectedOrigins": [],
  "correct": true,
  "problem": null
}

The check validates the manifest contents but does not verify that the manifest's path resolves to an existing executable.

Recovery attempted

A full supported clean reinstall did not restore latest:

  1. Fully quit Chrome and ChatGPT.
  2. Remove the Chrome plugin and browser extension.
  3. Restart both applications.
  4. Reinstall the plugin and extension into the selected Chrome profile.
  5. Confirm the extension is installed and enabled.
  6. Start a fresh Codex chat and retry.
  7. Restart again and retry.

The versioned plugin directory is recreated, but latest remains absent and browser control remains unavailable.

Two changes would make this failure actionable: preserve/atomically recreate latest during reconciliation, and make the manifest diagnostic require that the configured host path exists and is executable.

mdpatrick · 15 days ago

This is really annoying and affecting multiple computers I own and also a peer's. It's obviously super widespread. @tibo-openai

mdpatrick · 15 days ago
fare-sys · 15 days ago

Fresh reproduction on 2026-08-12 with the current macOS desktop/plugin release:

  • macOS 26.5.2 (arm64)
  • ChatGPT/Codex desktop 26.803.81509 (build 6415)
  • chrome@openai-bundled 26.803.81509
  • Google Chrome 151.0.7922.109
  • ChatGPT Chrome Extension 1.2.27259.19709

The bundled Chrome plugin was reinstalled and Chrome was explicitly invoked with @chrome, but the Chrome backend remained unavailable:

Browser is not available: chrome

agent.browsers.list() exposed only the in-app browser.

The bundled diagnostics reported Chrome running, the extension installed/enabled, and the Native Messaging manifest correct: true. However, the manifest's configured executable resolved through:

~/.codex/plugins/cache/openai-bundled/chrome/latest/extension-host/macos/arm64/ChatGPT for Chrome

That path did not exist because chrome/latest was absent. The real versioned executable did exist and was executable at:

~/.codex/plugins/cache/openai-bundled/chrome/26.803.81509/extension-host/macos/arm64/ChatGPT for Chrome

The Chrome plugin cache root contained only 26.803.81509/; there was no latest entry. No native-host process started when the extension was opened.

This confirms the bug persists in 26.803.81509 and that check-native-host-manifest.js can still return correct: true without verifying that manifest.path resolves to an existing executable. Reinstalling the bundled plugin did not restore the missing alias.

BestLessonEver · 15 days ago

I can reproduce this independently on a newer build, including after a clean uninstall/reinstall through the official UI.

Environment

  • ChatGPT desktop / Codex: 26.803.61601 (CFBundleVersion 6396)
  • Chrome plugin: chrome@openai-bundled 26.803.61601
  • Google Chrome: 151.0.7922.109
  • ChatGPT Chrome extension: 1.2.27236.6274_0
  • macOS, Apple Silicon / arm64

Clean reproduction

  1. Uninstalled the Chrome plugin through plugin management.
  2. Verified both the plugin cache and Chrome native-messaging manifest were removed.
  3. Reinstalled the Chrome plugin from ChatGPT Settings → Plugins.
  4. The UI and installation log reported success (plugin_install_succeeded).

Immediately after reinstall, the cache contained only:

~/.codex/plugins/cache/openai-bundled/chrome/
└── 26.803.61601/

There was no latest symlink/directory.

The recreated manifest at:

~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.openai.codexextension.json

pointed to:

~/.codex/plugins/cache/openai-bundled/chrome/latest/extension-host/macos/arm64/ChatGPT for Chrome

That target does not exist. The signed executable does exist at the equivalent path under 26.803.61601/.

I also found extension-host-config.json absent from the plugin cache.

Runtime result

  • Chrome is running and the ChatGPT extension is installed/enabled.
  • The native host process never launches.
  • The desktop browser runtime lists only the in-app browser.
  • Requesting Chrome returns: Browser is not available: chrome.
  • Opening a fresh Chrome window does not help.
  • Reinstalling does not help; it recreates the same broken state.

Diagnostic false positive
The bundled check-native-host-manifest.js --browser chrome --json reports correct: true even though the manifest's executable path does not exist. The checker appears to validate manifest identity/origins/path text but not that the resolved target exists and is executable.

This narrows the current failure beyond later cache reconciliation: on 26.803.61601, the official reinstall flow itself can report success while creating the versioned directory and a manifest that depends on a missing latest alias.

Suggested acceptance criteria:

  • Atomically create/update chrome/latest during install and reconciliation.
  • Validate that the manifest target exists and is executable before reporting install success.
  • Make the diagnostic checker fail when the target is missing or non-executable.
  • Recreate any required host config during repair/reinstall.

I did not apply a manual symlink workaround, so the state above is the unmodified result of the official reinstall flow.

scott-cmd11 · 7 days ago

Confirming a closely related variant: on this machine the breakage happens on every version change, not just same-version reconciliation — the updater installs the new versioned directory and deletes the old one, but never repoints latest. Recurrence log (macOS arm64, Mac mini M4):

  1. 2026-08-05: latest -> 26.727.51351 (deleted); 26.730.61639 present → dangling
  2. 2026-08-07 06:05: latest -> 26.730.61639 (deleted); 26.803.41515 present → dangling
  3. 2026-08-11 13:59: latest -> 26.803.41515 (deleted); 26.803.61601 present → dangling
  4. 2026-08-15 18:09: latest -> 26.810.41047 (deleted); 26.810.52044 present → dangling

4/4 plugin updates stranded the symlink. Symptom each time: Browser is not available: chrome even though Chrome is running, the extension is enabled, and the native-host manifest is valid — because the manifest path resolves through latest and the spawn fails with ENOENT.

Two extra findings that may help triage:

  • Diagnostic blind spot: all four bundled scripts (chrome-is-running.js, installed-browsers.js, check-extension-installed.js, check-native-host-manifest.js) exit 0 while the bridge is completely broken, because check-native-host-manifest.js validates the manifest's JSON fields but never checks that path exists on disk. Suggest adding an existence+executable check on the resolved host path.
  • Aggravator: a full plugin-cache volume (ENOSPC) appears to make mid-install failures more likely. After freeing disk space the 2026-08-20 update to 26.814.41957 was the first one that did NOT strand latest (unclear if fixed or lucky).

Also worth noting two related failure modes seen while diagnosing (may deserve their own issues):

  • Stale resident host: the bridge can die while every process looks alive (dead socket between the resident ChatGPT for Chrome host and the app-server, e.g. after sleep/wake). Killing the host process is sufficient — Chrome's extension reconnects and Chrome spawns a fresh host within seconds; the bridge self-heals with no app restart.
  • Stale per-session bindings: after any host replacement, long-running Codex threads lose their browser binding and report Browser is not available: chrome while fresh sessions work fine. Recovery requires resetting the session's JS runtime or starting a new thread; sessions should ideally re-bind automatically.

Local workaround in use (self-healing watchdog): an hourly launchd job that verifies latest resolves to a directory containing an executable host binary and repoints it to the newest valid cached version when stranded.