Chrome control broken in WSL-agent mode: native-messaging host manifest written with un-translated /mnt/c path (and non-existent 'latest' segment)
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 packageOpenAI.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 hostcom.openai.codexextensionregistered inHKCU\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:
- 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/cwas never converted toC:. 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 beC:\Users\<user>\.codex\....
- Non-existent
latestversion segment. The manifest uses...\chrome\latest\..., but the only installed version directory is...\chrome\26.623.31921\.... There is nolatestalias/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
- Windows + WSL2, Codex Desktop with
runCodexInWindowsSubsystemForLinux = true. - Enable the
chrome@openai-bundledplugin and install the Codex Chrome extension. - Ask Codex to control Chrome (e.g. open a page / read a field).
- Observe: nothing happens. Inspect
%LOCALAPPDATA%\OpenAI\extension\com.openai.codexextension.json— thepathfield 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.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I checked this against the current checkout and a few installed Desktop/plugin states over SSH.
Findings:
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/....installManifest.mjsstill canonicalizes a versioned plugin root back to../latestbefore writingbrowserClientPathandextensionHostPath. That means the generated manifest depends onlatestbeing a valid native link/junction.latestlink resolves.%LOCALAPPDATA%\OpenAI\extension\com.openai.codexextension.jsonpoints atC:\Users\ogosh\.codex\plugins\cache\openai-bundled\chrome\latest\extension-host\windows\x64\extension-host.exe, butTest-Pathis false. The concrete versioned target exists at...\chrome\26.623.31921\extension-host\windows\x64\extension-host.exe, and...\scripts\browser-client.mjsexists there too. So using the concrete installed version path would avoid this failure even when thelatestjunction/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:
/mnt/<drive>/...) to<DRIVE>:\...before replacing separators.latestlink before using it.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
latestalias itself is missing.Feedback ID:
019f9ec9-dca4-7f90-afff-e380b31a9ba2Environment
OpenAI.Codex 26.721.4979.026.721.410591.2.27221.15725DefaultObserved state
The Chrome extension is installed and enabled. The native messaging registry entry and manifest both exist:
The manifest points to:
That path does not exist because there is no
chrome\latestalias/directory. The actual executable exists only at:The Chrome side panel therefore shows:
Uninstalling/reinstalling the Chrome plugin did not recreate or repair the
latestalias.Diagnostic false positive
The bundled command:
returns:
However, it does not validate that the executable in
manifest.pathexists. This leaves the installer state broken while the official diagnostic reports success.Suggested regression coverage:
chrome\latestbefore writing the native-host manifest.check-native-host-manifest.jsshould resolvemanifest.pathand reportcorrect: falsewhen 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.
Still reproducible on a newer Codex Desktop build.
Environment:
26.721.4979.0x6410.0.26200.889324.04.4 LTS, kernel6.18.33.2-microsoft-standard-WSL2/mnt/c/Users/<user>/Documents/...Observed a real ghost directory on the Windows filesystem:
It was not just the normal WSL view of
C:\Users\<user>\.codex. The ghost tree occupied about 399 MB and contained: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 entireC:\mnttree.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 toC:\.... The ghost-tree behavior remains present in26.721.4979.0.Fresh current-build reproduction (2026-08-01) confirms both the mixed-path reconciliation failure and the missing-
latestdiagnostic blind spot.Environment
26.727.6591.00.146.0-alpha.9.226.727.513511.2.27236.6274_0Deterministic reconciliation sequence
The Desktop log records:
The success and ENOENT occur about five seconds apart. The malformed
C:\mnt\csignature 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
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.jsdoes not verify thatmanifest.pathresolves to an existing executable, so it returns a false green in this state.This is distinct from #29639. That issue rejects the WSL
sandboxCwdat Windows Node REPL before JavaScript runs; even after that is fixed, the absent native host here remains a downstream blocker.Suggested acceptance coverage:
/mnt/<drive>/...paths to native Windows drive paths exactly once at the Desktop/plugin-reconciliation boundary.chrome/latestbefore registering the native-host manifest.The path writer,
latestorchestration, 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.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 missingchrome\latestalias. WinBridge checks those relationships together: activeCODEX_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.