Chrome control broken in WSL-agent mode: native-messaging host manifest written with un-translated /mnt/c path (and non-existent 'latest' segment)

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

Summary

When Codex Desktop is configured to run the agent inside WSL (runCodexInWindowsSubsystemForLinux = true), the Chrome control feature is completely non-functional. The Chrome extension installs and the native-messaging host registers, but the native messaging host manifest is written with un-translated WSL paths, so Chrome can never launch the host. The browser tools silently do nothing.

Environment

  • OS: Windows 11 + WSL2 (Ubuntu)
  • Codex Desktop: 26.623.31921 (MSIX package OpenAI.Codex_26.623.4041.0_x64__2p2nqsd0c76g0)
  • Setting: runCodexInWindowsSubsystemForLinux = true (agent runs in WSL; CODEX_HOME = C:\Users\<user>\.codex)
  • Chrome extension "Codex" (hehggadaopoacecdllhhajmbjkdcmajg) installed and present; native host com.openai.codexextension registered in HKCU\Software\Google\Chrome\NativeMessagingHosts.

Root cause: WSL mount path written into a Windows-consumed manifest

The native messaging host manifest that Chrome actually reads —
C:\Users\<user>\AppData\Local\OpenAI\extension\com.openai.codexextension.json — contains:

{
  "allowed_origins": ["chrome-extension://hehggadaopoacecdllhhajmbjkdcmajg/"],
  "name": "com.openai.codexextension",
  "path": "\\mnt\\c\\Users\\<user>\\.codex\\plugins\\cache\\openai-bundled\\chrome\\latest\\extension-host\\windows\\x64\\extension-host.exe",
  "type": "stdio"
}

The path value is broken in two independent ways:

  1. WSL mount path not translated to a drive letter. \mnt\c\... is the WSL view /mnt/c/... with forward slashes replaced by backslashes — but /mnt/c was never converted to C:. Chrome is a Windows process, so it resolves \mnt\c\Users\... relative to the current drive root, i.e. C:\mnt\c\Users\..., which does not exist. The correct value should be C:\Users\<user>\.codex\....
  1. Non-existent latest version segment. The manifest uses ...\chrome\latest\..., but the only installed version directory is ...\chrome\26.623.31921\.... There is no latest alias/symlink on disk.

The same broken pattern appears in %LOCALAPPDATA%\OpenAI\Codex\chrome-native-hosts-v2.json (fields browserClientPath, codexCliPath, extensionHostPath all use \mnt\c\...\latest\...).

The correct, existing files are at:

C:\Users\<user>\.codex\plugins\cache\openai-bundled\chrome\26.623.31921\extension-host\windows\x64\extension-host.exe
C:\Users\<user>\.codex\plugins\cache\openai-bundled\chrome\26.623.31921\scripts\browser-client.mjs

Smoking gun

Because a Windows process was handed \mnt\c\..., Windows created a ghost mirror tree at C:\mnt\c\Users\<user>\.codex\..., into which some plugin-appserver binaries (codex.exe, codex-command-runner.exe, codex-windows-sandbox-setup.exe) were actually staged — instead of the real C:\Users\<user>\.codex\plugins\.plugin-appserver\. This confirms the path is being consumed verbatim by Windows-side components that cannot interpret a WSL mount path.

Impact

  • Chrome control via the extension is silently 100% broken in WSL-agent mode — no error surfaced to the user; the model's browser actions appear to "do nothing."
  • The plugin install is left scattered (real version dir + a bogus C:\mnt\c\... tree), so manual manifest patching is not durable: Codex Desktop regenerates these manifests on launch/plugin-sync and re-introduces the broken paths.

Expected behavior

When the agent runs in WSL, any path written into Windows-consumed artifacts (Chrome native-messaging host manifest, chrome-native-hosts-v2.json) must be translated from the WSL mount form (/mnt/c/...) to a Windows path (C:\...), and must resolve to the concrete installed version directory rather than a non-existent latest alias.

Steps to reproduce

  1. Windows + WSL2, Codex Desktop with runCodexInWindowsSubsystemForLinux = true.
  2. Enable the chrome@openai-bundled plugin and install the Codex Chrome extension.
  3. Ask Codex to control Chrome (e.g. open a page / read a field).
  4. Observe: nothing happens. Inspect %LOCALAPPDATA%\OpenAI\extension\com.openai.codexextension.json — the path field is \mnt\c\...\chrome\latest\...\extension-host.exe, which does not resolve.

Suggested fix

In the path-normalization step that emits Windows-side manifests under WSL-agent mode:

  • Convert /mnt/<drive>/... → <DRIVE>:\... (don't just swap slashes).
  • Resolve the actual installed version directory instead of writing latest.

View original on GitHub ↗

6 Comments

github-actions[bot] contributor · 2 months ago

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

  • #28956

Powered by Codex Action

Nicolas0315 · 2 months ago

I checked this against the current checkout and a few installed Desktop/plugin states over SSH.

Findings:

  • The native-host writer appears to live in the bundled Chrome plugin (scripts/installManifest.mjs), not in the openai/codex Rust plugin manager code in this repo. I do not see the source for that bundle in this checkout, only the installed/minified plugin artifact under .codex/plugins/cache/openai-bundled/chrome/....
  • The installed installManifest.mjs still canonicalizes a versioned plugin root back to ../latest before writing browserClientPath and extensionHostPath. That means the generated manifest depends on latest being a valid native link/junction.
  • On rtx4090, nicolas2025, cyberagent-mac-m5max, and nicolas-macbook-pro, current generated manifests use platform-native paths and the latest link resolves.
  • On rtx5060ti (Windows 11), I found a reproducible adjacent failure: %LOCALAPPDATA%\OpenAI\extension\com.openai.codexextension.json points at C:\Users\ogosh\.codex\plugins\cache\openai-bundled\chrome\latest\extension-host\windows\x64\extension-host.exe, but Test-Path is false. The concrete versioned target exists at ...\chrome\26.623.31921\extension-host\windows\x64\extension-host.exe, and ...\scripts\browser-client.mjs exists there too. So using the concrete installed version path would avoid this failure even when the latest junction/link is stale or non-traversable.

I do not have a repo patch to attach because the responsible bundled Chrome plugin source does not appear to be part of this repository. The fix still looks like it belongs in that bundle/native-host installer:

  1. When the writer is running on Windows or writing Windows-consumed artifacts, translate WSL drive mounts (/mnt/<drive>/...) to <DRIVE>:\... before replacing separators.
  2. Prefer the concrete installed plugin version directory when emitting native-host manifests, or verify/recreate the latest link before using it.
medking82 · 1 month ago

Reproduced on a newer Windows + WSL2 setup. This reproduction narrows the second failure mode in the issue: the manifest path is already a valid Windows path, but the latest alias itself is missing.

Feedback ID: 019f9ec9-dca4-7f90-afff-e380b31a9ba2

Environment

  • Codex Desktop: OpenAI.Codex 26.721.4979.0
  • Bundled Chrome plugin cache version: 26.721.41059
  • ChatGPT Chrome extension: 1.2.27221.15725
  • Chrome profile: Default
  • Agent/workspace runs through WSL2; Codex Desktop and Chrome run on Windows

Observed state

The Chrome extension is installed and enabled. The native messaging registry entry and manifest both exist:

HKCU\Software\Google\Chrome\NativeMessagingHosts\com.openai.codexextension
%LOCALAPPDATA%\OpenAI\extension\com.openai.codexextension.json

The manifest points to:

C:\Users\<user>\.codex\plugins\cache\openai-bundled\chrome\latest\extension-host\windows\x64\extension-host.exe

That path does not exist because there is no chrome\latest alias/directory. The actual executable exists only at:

C:\Users\<user>\.codex\plugins\cache\openai-bundled\chrome\26.721.41059\extension-host\windows\x64\extension-host.exe

The Chrome side panel therefore shows:

Install the app to use ChatGPT in Chrome

Uninstalling/reinstalling the Chrome plugin did not recreate or repair the latest alias.

Diagnostic false positive

The bundled command:

scripts\check-native-host-manifest.js --json

returns:

{
  "exists": true,
  "nameMatches": true,
  "hasExpectedOrigin": true,
  "registryMatchesManifestPath": true,
  "correct": true,
  "problem": null
}

However, it does not validate that the executable in manifest.path exists. This leaves the installer state broken while the official diagnostic reports success.

Suggested regression coverage:

  1. Plugin install/update/reinstall must atomically update or recreate chrome\latest before writing the native-host manifest.
  2. check-native-host-manifest.js should resolve manifest.path and report correct: false when the native-host executable is missing.

I am not attaching the browser screenshot publicly because it includes unrelated browsing context; the uploaded feedback ID above contains the app-side diagnostics.

artemiuss · 1 month ago

Still reproducible on a newer Codex Desktop build.

Environment:

  • Codex Desktop (Windows Store): 26.721.4979.0 x64
  • Windows: 10.0.26200.8893
  • WSL2: Ubuntu 24.04.4 LTS, kernel 6.18.33.2-microsoft-standard-WSL2
  • Workspace is Windows-backed and exposed to the agent as /mnt/c/Users/<user>/Documents/...

Observed a real ghost directory on the Windows filesystem:

C:\mnt\c\Users\<user>\.codex

It was not just the normal WSL view of C:\Users\<user>\.codex. The ghost tree occupied about 399 MB and contained:

plugins\.plugin-appserver\codex.exe
plugins\.plugin-appserver\codex-code-mode-host.exe
plugins\.plugin-appserver\codex-command-runner.exe
plugins\.plugin-appserver\codex-windows-sandbox-setup.exe
realtime-voice-continuity.json

The four executables in the ghost tree were not SHA-256-identical to the files at the expected location under C:\Users\<user>\.codex\plugins\.plugin-appserver, suggesting that the bad path can also leave a stale second app-server payload behind.

Before cleanup I confirmed that no process was running from C:\mnt\. I then manually removed the entire C:\mnt tree.

This corroborates the issue's path-normalization finding: a WSL path beginning with /mnt/c/... is reaching a Windows-side component as \mnt\c\... / C:\mnt\c\..., rather than being converted to C:\.... The ghost-tree behavior remains present in 26.721.4979.0.

medking82 · 26 days ago

Fresh current-build reproduction (2026-08-01) confirms both the mixed-path reconciliation failure and the missing-latest diagnostic blind spot.

Environment

  • Codex Desktop MSIX: 26.727.6591.0
  • Desktop-bundled Codex CLI: 0.146.0-alpha.9.2
  • Bundled Chrome plugin: 26.727.51351
  • Chrome extension: 1.2.27236.6274_0
  • Windows Desktop using a WSL-native workspace

Deterministic reconciliation sequence

The Desktop log records:

bundled_plugin_chrome_extension_sync_decision ... isExtensionInstalled=true isPluginInstalled=true
plugin_install_succeeded ... pluginName=chrome
bundled_plugins_marketplace_install_failed
ENOENT: access 'C:\mnt\c\Users\<user>\.codex\plugins\cache\openai-bundled\chrome\26.727.51351'
installPhase=reconcile_chrome_native_host

The success and ENOENT occur about five seconds apart. The malformed C:\mnt\c signature occurs more than 1,800 times in the local Desktop logs from 2026-07-23 through 2026-08-01, so this is repeatable reconciliation behavior rather than a one-time incomplete install.

Resulting filesystem and manifest state

C:\Users\<user>\.codex\plugins\cache\openai-bundled\chrome\26.727.51351\extension-host\windows\x64\extension-host.exe
  exists

C:\Users\<user>\.codex\plugins\cache\openai-bundled\chrome\latest
  missing

manifest target:
C:\Users\<user>\.codex\plugins\cache\openai-bundled\chrome\latest\extension-host\windows\x64\extension-host.exe
  missing

All four bundled read-only diagnostics report success: Chrome is installed/running, the extension is installed/enabled, and the native-host registry/name/origins match. However, check-native-host-manifest.js does not verify that manifest.path resolves to an existing executable, so it returns a false green in this state.

This is distinct from #29639. That issue rejects the WSL sandboxCwd at Windows Node REPL before JavaScript runs; even after that is fixed, the absent native host here remains a downstream blocker.

Suggested acceptance coverage:

  1. Convert WSL /mnt/<drive>/... paths to native Windows drive paths exactly once at the Desktop/plugin-reconciliation boundary.
  2. Materialize or atomically update chrome/latest before registering the native-host manifest.
  3. Reconcile a second time and assert the path remains valid and unchanged.
  4. Make the diagnostic fail when the manifest's executable target is absent.

The path writer, latest orchestration, and checker appear to live in bundled/private Desktop plugin code rather than this public Rust repository. Could a maintainer route this evidence to the owning team? If there is a public contribution surface, I would appreciate guidance and an invitation for a focused PR.

zemeng5208 · 13 days ago

I maintain WinBridge Recovery (independent Windows Codex Desktop recovery tooling): https://github.com/zemeng5208/winbridge-recovery

This report is a good example of why I treat Chrome integration as a multi-layer state rather than only checking whether the extension is installed. Here the versioned plugin directory is real, while Windows-consumed artifacts contain both a WSL-form path (\mnt\c\...) and a missing chrome\latest alias. WinBridge checks those relationships together: active CODEX_HOME, concrete plugin version, latest, native-host manifest/registry, chrome-native-hosts-v2.json, and referenced runtime executables.

One important scope limit: the /mnt/c → Windows path conversion bug described here is an upstream regeneration bug. A local repair can diagnose the inconsistency and, where safe, restore locally generated pointers/aliases from the official installed package, but it cannot make a durable promise if Codex Desktop rewrites the same bad WSL paths on the next reconciliation. In that case WinBridge should classify the result as partial/upstream rather than repeatedly fighting Desktop.

If anyone on this thread tests WinBridge against this exact combination (bad WSL path + missing latest), please leave even a one-line outcome here: https://github.com/zemeng5208/winbridge-recovery/issues/4 — ✅ fixed, 🟡 temporary/partial, and ❌ unchanged are all useful for separating recoverable local drift from the upstream path-normalization defect.