[Desktop Linux] Plugins page fails with "AbsolutePathBuf deserialized without a base path" when a local project lives on an NTFS/ntfs3 mount

Open 💬 0 comments Opened Aug 26, 2026 by iiishop

Summary

On Codex Desktop (Linux native, Arch Linux), the Plugins page fails to load with:

Invalid request: AbsolutePathBuf deserialized without a base path

whenever a local project on an NTFS mount (/mnt/d/..., ntfs3) is present in the desktop project list. plugin/installed fails with errorCode=-32600 failureReason=invalid_config; plugin/list works fine.

This is the same AbsolutePathBuf deserialization class as #20014 / #23213 / #30436, but on a Linux-native trigger that I don't think has been reported: the failing cwd is a perfectly valid absolute POSIX path on an ntfs3 mount, not a Windows path and not a virtual-workspace path.

Environment

  • OS: Arch Linux (Linux 7.1.8-arch1-3), native desktop app (no WSL)
  • ChatGPT desktop package: chatgpt-desktop 26.818.61809-1 (also reproduced on 26.818.22352)
  • codex-cli: 0.148.0-alpha.21 (/usr/lib/chatgpt/resources/codex)
  • Mount: NTFS data drive at /mnt/d via ntfs3 (rw,uid=1000,gid=1000,dmask=0022,fmask=0022,windows_names,acl,iocharset=utf8,prealloc)

Reproduction

  1. Add any local project whose root lives on an NTFS/ntfs3 mount to the desktop project list (e.g. /mnt/d/FromGithub/SomeRepo). This writes a local-projects entry in ~/.codex/.codex-global-state.json.
  2. Open the desktop app, go to Plugins.
  3. The plugin list fails to load with the AbsolutePathBuf error above.

Desktop log (from ~/.local/state/codex/logs/.../codex-desktop-*.log):

info [AppServerConnection] response_routed ... method=plugin/installed ... errorCode=-32600
error [electron-message-handler] Request failed ... error={"code":-32600,"message":"Invalid request: AbsolutePathBuf deserialized without a base path"} failureReason=invalid_config method=plugin/installed source=plugins

What I verified

  • The failing path itself is healthy on Linux: realpath /mnt/d/FromGithub/StratumCode succeeds, stat succeeds, and codex exec runs fine with cwd inside that directory.
  • .git config contains no Windows path references; no case-sensitivity issue (ntfs3 here is case-sensitive as mounted).
  • Removing the NTFS-mounted project from ~/.codex/.codex-global-state.json (local-projects + project-order) and restarting the app makes plugin/installed return errorCode=null immediately. Re-adding an ordinary $HOME project (e.g. ~/Projects/omibar) stays clean. The trigger is specifically the NTFS-mounted project.
  • The desktop projects live in ~/.codex/.codex-global-state.json (local-projects), which is a separate store from [projects.xxx] in ~/.codex/config.toml; editing config.toml alone does not affect this path.

Suspected root cause

The renderer sends the project roots as cwds to plugin/installed (same shape as in #20014). workspace-root-options handler canonicalizes roots and its implementation swallows realpath failures with catch { return null } — a failed realpath on the ntfs3 path can inject null (or a non-absolute residue) into cwds, and since AbsolutePathBuf deserialization without a guard is all-or-nothing (per the schema comment: "will fail unless the path being deserialized is already absolute"), one bad entry kills the whole request.

I could not observe the exact value inside cwds (renderer internals), so the null/canonicalization-residue part is a hypothesis — but the trigger (NTFS-mounted project in the desktop project list) is confirmed by the remove/restart test above.

Workaround (for affected users)

Remove NTFS-mounted projects from the desktop project list — either via the UI, or by editing ~/.codex/.codex-global-state.json (remove the entry from local-projects and project-order) while the app is closed. CLI usage (codex exec / codex plugin list) is unaffected.

Suggested fix

Two options, in order of robustness:

  1. In the workspace-root-options / plugin/installed path, drop entries whose canonicalization fails instead of injecting null/residue into cwds — a bad root should be skipped, not kill the whole request (the all-or-nothing deserialization is the underlying papercut; #36680 makes the same point).
  2. Wrap the plugin/installed (and plugin/list) request deserialization in AbsolutePathBufGuard so that relative/residue paths are resolved against a base instead of rejected — matching the fix pattern already applied to agent-role config in #19257 / #19261.

Related issues

  • #20014 — Plugins page fails in WSL mode when plugin/list receives Windows cwd
  • #23213 / #23209 — new-chat creation fails with the same error
  • #30436 — Windows Desktop + WSL: same error class, closed as completed Jul 3 2026
  • #36680 — VS Code: virtual (non-file scheme) workspace folder triggers the same error

View original on GitHub ↗