openai / openai/codex

Windows Desktop + WSL2: inline Visualize silently fails because /mnt/c/... is normalized as a Windows root path

Open
#40,100 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug skills windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of the Codex App are you using?

Codex Desktop for Windows.

  • Release shown in logs: 26.818.31338
  • Microsoft Store package: OpenAI.Codex_26.818.3698.0_x64__2p2nqsd0c76g0
  • Bundled Visualize plugin: 1.0.22
What subscription do you have?

Not relevant to this local Desktop path-handling reproduction.

What platform is your computer?

Windows 11 x64 with the Codex agent configured to run in WSL2 Ubuntu.

WSL kernel:

Linux 6.6.87.2-microsoft-standard-WSL2 x86_64
What issue are you seeing?

An inline visualization created by a WSL2-backed Codex task does not render in Codex Desktop. The visualization placeholder disappears without a chart or a useful file-read error.

The agent receives a thread-scoped visualization directory on the Windows filesystem through its WSL mount:

/mnt/c/Users/<windows-user>/.codex/visualizations/YYYY/MM/DD/<thread-id>

The agent writes a valid HTML fragment there and the final response references its absolute WSL path:

visualize{"path":"/mnt/c/Users/<windows-user>/.codex/visualizations/YYYY/MM/DD/<thread-id>/minimal.html","mode":"wide","title":"Minimal visualization"}

The file exists. wslpath -w resolves it to the expected native path:

C:\Users\<windows-user>\.codex\visualizations\YYYY\MM\DD\<thread-id>\minimal.html

The observed fragment was 34,069 bytes, below the 5 MB limit. Its JavaScript parsed successfully and the fragment had none of the disallowed document wrappers or escaped-markup artifacts. The content layer is therefore not the failing layer.

Root-cause evidence

The packaged Desktop visualization read service receives the path, obtains the execution host's platform path implementation, normalizes the supplied path, performs containment checks, and then calls the execution host's stat and readFile methods.

With Windows path semantics, the relevant transformation is:

input:      /mnt/c/Users/<windows-user>/.codex/visualizations/.../minimal.html
normalized: \mnt\c\Users\<windows-user>\.codex\visualizations\...\minimal.html

Node's Windows path implementation considers the input absolute. Its relative-path containment check also succeeds against a matching /mnt/c/... writable root. The read then reaches the native Windows filesystem with \mnt\c\..., which resolves on the current drive as the nonexistent mixed path C:\mnt\c\... instead of C:\Users\....

This isolates the defect to the Desktop path boundary: a WSL absolute path is validated with Windows path semantics but is not converted to a Windows path before native file access. The Desktop log identifies the renderer platform as Windows and the task environment as WSL-disabled for Windows-native browser features:

browser_use_availability_resolved available=false platform=Windows reason=wsl-disabled release=26.818.31338

The visualization read failure itself is not logged with the requested or resolved path, which makes the UI failure silent.

Steps to reproduce
  1. Use Codex Desktop on Windows 11.
  2. Configure the agent environment to use WSL2 Ubuntu.
  3. Start a task whose visualization writable root is exposed to WSL under /mnt/c/Users/<windows-user>/.codex/visualizations/....
  4. Ask Codex to create a minimal inline visualization with the bundled Visualize plugin.
  5. Confirm the generated fragment exists with stat.
  6. Confirm wslpath -w <absolute-fragment-path> resolves to C:\Users\<windows-user>\....
  7. Let the response emit the inline visualization reference containing the absolute /mnt/c/... path.
  8. Observe that the visualization does not render and no actionable error is shown.
Expected behavior

Codex Desktop should preserve the filesystem authority associated with the path.

For an agent-created /mnt/<drive>/... path, Desktop should do one of the following before native Windows file access:

  • convert it to the corresponding Windows path, such as C:\Users\...;
  • delegate stat and readFile to the WSL execution host that created the path;
  • materialize the fragment as a renderer asset through an explicit host-neutral transfer boundary.

If the read fails, the inline placeholder should remain visible and show the requested path, resolved path, execution host, and file-read error.

Actual behavior

The app silently drops the inline visualization. The file remains present at the correct WSL and Windows-equivalent location.

Related issues
  • #32054 reports the same silent visualization disappearance when the renderer resolves a valid fragment under the wrong .codex/visualizations owner. That report is macOS and concerns workspace-relative versus home-relative resolution.
  • #24268 records the same Windows + WSL mixed-path result, C:\mnt\c\..., in bundled plugin reconciliation.
  • #29413 and #33560 record /mnt/c/... reaching native Windows browser runtimes without conversion.
  • #32183 contains another observed C:\mnt\c\... access failure and groups related Windows + WSL path-boundary defects.

This appears related to those issues but is not an exact duplicate. It affects the inline visualization file reader and reproduces with the absolute path supplied by the visualization protocol.

Privacy note

User names, thread identifiers, project names, and visualization contents are redacted. A minimal fragment and sanitized log excerpt can be supplied if needed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the Desktop visualization read service and its execution-host path/stat/readFile boundary; reproduce with an absolute /mnt/c/... fragment and inspect the normalized path and containment check. Done means the fragment is read through the correct Windows/WSL boundary, or a visible error reports the requested and resolved paths, execution host, and read failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
linux, node.js
Domain
desktop, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.