CLI: resume/fork on WSL can restore lowercased cwd from SQLite-normalized path

Resolved 💬 2 comments Opened Mar 3, 2026 by ignatremizov Closed Mar 3, 2026
💡 Likely answer: A maintainer (etraut-openai, contributor) responded on this thread — see the highlighted reply below.

What version of Codex CLI is running?

0.107.0

What subscription do you have?

Pro

Which model were you using?

gpt-5.3-codex

What platform is your computer?

Linux (WSL2), workspace under /mnt/c/...

What terminal emulator and version are you using (if applicable)?

Windows Terminal + WSL2 shell (bash/zsh)

What issue are you seeing?

resume / fork now restores a lowercased working directory on WSL mounts (for example /mnt/c/users/name/project), even when the original path casing was /mnt/c/Users/Name/Project.

That lowercased restored cwd can break downstream behavior that is case-sensitive at the string layer (for example trust/workspace config checks and unified exec command/tooling integrations that expect canonical Windows-style casing).

This looks like a regression from the change to read cwd from SQLite metadata first during resume/fork. SQLite stores a normalized cwd (including WSL lowercasing), and that normalized value is now reused as the actual fallback cwd, not just for comparison.

Related prior fix: #7995 (case-insensitive matching on WSL). This report is about a new side effect: normalized lowercase path being used as the resumed execution cwd.

What steps can reproduce the bug?

  1. In WSL, open a repo from a mixed-case Windows-mounted path, for example:
  • cd /mnt/c/Users/Name/Project
  1. Start a session and do at least one turn so session metadata is persisted.
  2. Exit Codex.
  3. Resume or fork that session (codex resume or codex fork) with SQLite enabled (default path).
  4. Inspect environment context / cwd used by the resumed session.

Observed: cwd can become a lowercased variant from normalized SQLite metadata (for example /mnt/c/users/name/project) instead of preserving original casing.

What is the expected behavior?

Resume/fork should preserve the original/usable cwd casing for execution context.

Path normalization should be used for equality/comparison only, not as the execution cwd that gets restored.

Additional information

Likely regression commit:
- c1afb8815af63c59b67824a73750884aa1a2e363 (tui: use thread_id for resume/fork cwd resolution) by @charley-oai

Relevant code points:

  • codex-rs/tui/src/lib.rs (read_session_cwd, resolve_cwd_for_resume_or_fork)
  • codex-rs/core/src/state_db.rs (normalize_cwd_for_state_db)
  • codex-rs/core/src/path_utils.rs (normalize_for_path_comparison, WSL /mnt/<drive> lowercasing)

Potential fix direction:

  • Keep normalized cwd in SQLite for matching/indexing,
  • but preserve/store an execution-display cwd separately (or reconstruct from rollout) for resume/fork fallback cwd selection.

Temporary Workaround

set

[features]
sqlite = false

in config.toml until this is fixed

View original on GitHub ↗

2 Comments

ignatremizov · 5 months ago

If anyone needs to fix path casing for an already-active session, this worked reliably for me:

1) Check all persistence layers for the same session, not just one:

  • session rollout JSONL in ~/.codex/sessions/.../rollout-...jsonl
  • state DB in ~/.codex/state_*.sqlite (usually threads.cwd)

2) Pick one canonical path string, for example /mnt/c/Users/Name/Project (preferably matching the case seen in Windows and inside WSL, even if it's possible to cd via other casings).

3) Patch both session-level and turn-level metadata:

  • threads.cwd in SQLite
  • any turn_context.cwd and tool-call workdir entries in the rollout JSONL for that session

4) Exit the CLI, then resume the session again.

If it still reverts, the resume loader is likely deriving cwd from runtime environment and overriding persisted thread state; in that case, fixing only SQLite or JSONL is not sufficient, but I did not have this issue. After turning off sqlite and patching the directories in JSONL, functionality was restored.

etraut-openai contributor · 5 months ago

Thanks for the bug report. This should be fixed in the next release with this PR.