Skip to content

Windows + WSL: independent failures in Linux helper isolation, project-root RPC conversion, and persisted thread cwd #44918

Open

Description

@Bruce-anle

I am opening this as a new issue because existing reports cover individual symptoms, while this local investigation adds concrete reproductions, code changes, and end-to-end validation. The failures share the Windows/WSL surface, but have independent first supported causes; this report does not claim one common root cause.

Live Desktop validation used Windows 11, WSL2 Ubuntu, Codex Desktop 26.903.9818.0, the WSL Agent Environment, and the codex-cli/app-server 0.154.0 line. One malformed persisted cwd still contained an older 26.903.8094.0 Appx resource path; that is historical stored data, not the live executable. User-specific paths below are redacted as <windows-user>, <linux-user>, and <codex-home>.

1. Patch 1: Linux arg0 helper isolation

In a Windows-backed shared Codex home, the Windows sidecar and the WSL/Linux runtime can use the same <codex-home>/tmp/arg0 directory while expecting different helper formats. Local evidence establishes a missing/unusable Linux helper as a pre-exec failure mode, but does not identify which historical process, if any, removed a particular helper. Related upstream reports show similar symptoms, but do not prove a cross-OS collision.

Failed to create unified exec process: No such file or directory (os error 2)

This is the helper lifecycle/missing-helper family described by #40583 and #27462. Those reports are related symptoms, not proof of the same deletion mechanism.

In arg0/src/lib.rs, the local candidate changes prepare_path_entry_for_codex_aliases so Linux uses <codex-home>/tmp/arg0-linux, while Windows remains on <codex-home>/tmp/arg0. The test creates a legacy janitor fixture under the legacy root; that fixture is removed, while the isolated Linux helper remains. Eight focused tests passed. The test unlocks the Linux helper before the janitor runs, so survival does not depend on a cross-OS lock being shared correctly. These are direct observations; the historical deletion actor remains unknown.

A later os error 2 occurred with the helper present; an explicit valid /tmp made it run, supporting a separate invalid-default-cwd cause. Not every os error 2 is therefore an arg0 failure.

2. Patch 2: WSL project creation/import/update rejects Windows and UNC roots

The practical consequence was that, because I could not add a project in WSL mode, I temporarily switched to Windows native mode to complete the add, then switched back to WSL mode.

While running that WSL-hosted project in Windows native mode, commands failed before launch with setup refresh had errors, which required switching back to WSL. Earlier diagnosis recorded Windows sandbox GetSecurityInfo and GetNamedSecurityInfoW returning 1; equivalent Get-Acl outside the sandbox also returned 1, while the directory was readable and the Windows NTFS control case succeeded. This is historical evidence, not a fresh reproduction, and does not show that either patch fixes Windows ACL or sandbox behavior.

With the Agent Environment set to WSL/Ubuntu, selecting a project through the Windows folder picker using a path such as:

\\wsl.localhost\Ubuntu\home\<linux-user>\repro

produced the generic UI error “Create project failed” and did not add the project. The app-server log exposed the underlying failure:

Local app-server project migration failed
AbsolutePathBuf deserialized without a base path

The smallest protocol-level reproduction is to send a Windows drive path or WSL UNC path in ProjectRoot.path to the WSL app-server. The Linux app-server rejects it at AbsolutePathBuf deserialization, before the project handler can create or update the project. The control input, an already-native path such as /home/<linux-user>/repro, is accepted by the same app-server path logic.

Expected behavior is to convert the picker representation to the selected WSL distribution’s native path before strict Linux path validation:

\\wsl.localhost\Ubuntu\home\<linux-user>\repro
    -> /home/<linux-user>/repro

Against source commit 6b9826e3aa83b1a5947db50f4332cb9c65f1b340, the local candidate changed app-server-protocol/src/protocol/v2/project.rs and app-server/src/request_processors/projects.rs, with focused coverage in app-server/tests/suite/v2/projects.rs. It reused the existing LegacyAppPathString representation and added one shared asynchronous conversion/validation path for project create, import, and update:

  • Native Linux absolute paths pass through unchanged.
  • On Linux with WSL_DISTRO_NAME, Windows drive paths and current-distro \\wsl$\<distro>\... or \\wsl.localhost\<distro>\... paths are converted with wslpath -u.
  • Relative paths, other distros, ordinary network shares, and a missing converter are rejected explicitly.
  • Existing strict AbsolutePathBuf, canonical-root, and duplicate checks run on the converted value before any store mutation.

Two focused Rust RPC tests and isolated stdio checks passed for create/import/update, native readback, duplicate rejection, unsupported-path rejection, and no-write behavior on conversion failure. The final runtime merged Patch 1 and Patch 2 and was started through the Desktop shortcut. In Desktop validation, local-project migration completed and selecting a WSL UNC directory succeeded. Root and child tasks ran without an explicitly supplied working directory; each pwd returned the expected native Linux project directory, and a child task completed and returned its native final result.

3. Separate one-time recovery for an existing thread cwd

The initial Desktop function that generated the malformed cwd was not identified; the affected persistence and recovery sources were identified instead.

Switching between Windows and WSL can leave an already existing thread with a mixed persisted cwd similar to:

/mnt/c/Program Files/WindowsApps/.../app/resources/C:\mnt\c\Users\<windows-user>\.codex

Without an explicit working directory, this state can independently produce os error 2. The value was present in the WSL thread database, the latest rollout settings event, and the Desktop thread catalog; changing only one field is insufficient because another source can win during resume.

For this one existing thread, I fully stopped Desktop, made consistent backups, appended a corrected settings event, and synchronized the matching metadata/catalog cwd to the intended WSL cwd. Old history was retained. After restarting, an implicit pwd returned the intended native cwd. This was a separate one-time offline repair; it was not part of either runtime patch.

This one-time recovery does not implement permanent cross-mode migration or rewrite other historical threads.

Related reports and request

The closest existing reports are:

  • #40583 and #27462: related Linux/Windows pre-exec and missing-helper symptoms; they do not prove the same collision or deletion mechanism.
  • #44507 and #44512: WSL project creation/migration failures involving AbsolutePathBuf deserialized without a base path.
  • #41746: a WSL UNC alias case where selecting \\wsl.localhost\... did not persist the project.
  • #42292: cross-environment thread cwd persistence and mismatch between session and stored cwd.
  • #30435: explicit working-directory behavior that can bypass a bad default cwd.
  • #44022: WSL project add/remove failures where a native restart restored the project; this is related symptom evidence only.
  • #44182: WSL switching with a mixed app/resources/C: path and related symlink/path-selection behavior; only the path portion is relevant here, not its separate image-access scope.
  • #44454: WSL project create/save failure, related as a symptom report only.

As of 2026-09-12, I found no linked upstream branch or released fix that covers these behaviors. Please consider whether the project-root conversion should live in the Desktop picker, the project-root wire contract, or at the WSL app-server boundary, and ensure migration plus project create/import/update use the same rules. For helper paths, the runtime/host ownership should be explicit so a helper cleanup path cannot remove or replace a Linux helper it does not own. For persisted threads, resuming an environment-switched thread should validate and repair the cwd namespace instead of replaying a mixed path.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    app-serverIssues involving app server protocol or interfaces
    sessionIssues involving session (thread) management, resuming, forking, naming, archiving
    tool-callsIssues related to tool calling
    on Sep 11, 2026
  2. Synistic commented on Sep 15, 2026

    @Synistic

    I can reproduce this with the following setup:

    • Windows desktop package: 26.908.9136.0
    • WSL2 with Ubuntu
    • Bundled WSL backend: codex-cli 0.154.0-alpha.6.2

    Switching the agent environment provides a consistent comparison:

    1. Windows native + app restart: creating projects works.
    2. WSL + app restart: creating new projects fails.
    3. Switching back to Windows native restores project creation.

    The failure affects all three cases:

    • Selecting a Windows folder.
    • Selecting a WSL folder through its UNC path.
    • Creating a project without selecting any source folder.

    The UI only shows “Projekt konnte nicht erstellt werden”
    (“Project could not be created”).

    Additional protocol-level testing using a separately launched bundled
    WSL app-server:

    • project/create with C:\Users<user>\Documents:
      -32600: “Invalid request: AbsolutePathBuf deserialized without a base path”
    • project/create with \wsl$\Ubuntu\home<user><project>:
      Same error.
    • project/create with /home//:
      Succeeds and returns the project on readback.

    Inspection of the installed desktop bundle also showed that creating
    a project without source folders generates a default workspace under
    the Windows Documents\ChatGPT directory. This may explain why that
    case is affected as well.

    The protocol tests demonstrate the path incompatibility, but I have
    not captured the exact failing UI request, so I cannot confirm that
    every UI failure occurs at the same call.

    Could the Windows-to-WSL path conversion be checked for project
    creation, import/update, and automatically generated workspace paths?
    Exposing the underlying error in the UI would also help.

  3. Bruce-anle commented on Sep 19, 2026

    @Bruce-anle
    Author

    Update: With Codex Desktop 26.915.4065.0 and the bundled WSL backend 0.155.0-alpha.9.2, I can now add a WSL project through \\wsl$\Ubuntu\... successfully without the local patches. The project is stored with the correct Linux path.

    I also created a new task in that project. The main agent and a subagent successfully accessed the project files and completed a file-renaming task.

    The project-add failure no longer reproduces in this test. Thanks @Synistic for the detailed reproduction on the earlier version.

  4. Synistic commented on Oct 12, 2026

    @Synistic

    Tested and resolved, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingsessionIssues involving session (thread) management, resuming, forking, naming, archivingtool-callsIssues related to tool callingwindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions