codex - 💡(How to fix) Fix Codex Desktop new chat in SSH remote project can use stale Cloud/local environment in composer

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Codex Desktop can enter an inconsistent project/environment state where the sidebar and tooltip show a selected SSH remote project, but the new-chat composer is still bound to a stale Cloud Codex environment. In the same local state file, active-workspace-roots pointed at a Windows local project, and active-remote-project-id pointed at a different SSH remote project.

This is not just a display nit: it creates ambiguity about where a new agent session will actually run and which repository/environment it will modify.

Root Cause

For a coding agent, mixing local, SSH remote, and Cloud environments in the same composer is high-impact. A user may believe they are starting work in an SSH remote project, while the composer appears to target a different Cloud repo/environment. That can lead to commands, file reads, or code edits happening in the wrong repository or execution environment.

At minimum, the UI should not allow a new chat to show a selected SSH remote project while retaining a stale Cloud environment selector. Ideally the state reconciliation should make these selections mutually consistent, or explicitly block/send a warning when they are not.

Fix Action

Fix / Workaround

Workaround attempted

Code Example

{
  "selected-remote-host-id": "remote-ssh-codex-managed:<remote-host-label>",
  "remote-projects": [
    {
      "id": "<remote-project-id-A>",
      "hostId": "remote-ssh-codex-managed:<remote-host-label>",
      "remotePath": "/Users/<user>/Code/<remote-project>",
      "label": "<remote-project>"
    },
    {
      "id": "<remote-project-id-B>",
      "hostId": "remote-ssh-codex-managed:<remote-host-label>",
      "remotePath": "/Users/<user>/Code/<other-remote-project>",
      "label": "<other-remote-project>"
    }
  ],
  "active-workspace-roots": "D:\\Code\\<local-project>",
  "active-remote-project-id": "<remote-project-id-B>",
  "project-order": [
    "<remote-project-id-A>",
    "D:\\Code\\<local-project>",
    "<remote-project-id-B>",
    "cloud:<owner>/<another-cloud-repo>",
    "cloud:<owner>/<cloud-repo>"
  ],
  "electron-persisted-atom-state": {
    "environment": {
      "label": "<owner>/<cloud-repo>",
      "workspace_dir": "/workspace",
      "repos": ["<cloud-repo-id>"],
      "repo_map": {
        "<cloud-repo-id>": {
          "repository_full_name": "<owner>/<cloud-repo>",
          "default_branch": "main"
        }
      }
    },
    "last-used-continue-in-mode": "cloud"
  }
}
RAW_BUFFERClick to expand / collapse

Summary

Codex Desktop can enter an inconsistent project/environment state where the sidebar and tooltip show a selected SSH remote project, but the new-chat composer is still bound to a stale Cloud Codex environment. In the same local state file, active-workspace-roots pointed at a Windows local project, and active-remote-project-id pointed at a different SSH remote project.

This is not just a display nit: it creates ambiguity about where a new agent session will actually run and which repository/environment it will modify.

Why this matters

For a coding agent, mixing local, SSH remote, and Cloud environments in the same composer is high-impact. A user may believe they are starting work in an SSH remote project, while the composer appears to target a different Cloud repo/environment. That can lead to commands, file reads, or code edits happening in the wrong repository or execution environment.

At minimum, the UI should not allow a new chat to show a selected SSH remote project while retaining a stale Cloud environment selector. Ideally the state reconciliation should make these selections mutually consistent, or explicitly block/send a warning when they are not.

Environment

  • Product: Codex Desktop
  • Local platform: Windows 10, x64
  • Observed Codex Desktop package version from process path: 26.527.3686.0
  • Remote host type: SSH remote Mac host
  • Remote host platform: macOS 26.4.1, arm64
  • SSH connection status: connected/green in the UI
  • State file inspected: %USERPROFILE%\.codex\.codex-global-state.json

What I saw

The UI simultaneously showed:

  • Sidebar/project row: <remote-project> · <remote-host> with a green connected status
  • Path tooltip: /Users/<user>/Code/<remote-project>
  • New-chat tooltip: Start a new chat in <remote-project>
  • New-chat page heading: asking what to do in <remote-project>
  • Composer environment selector: <owner>/<cloud-repo> · main, with tooltip Select cloud environment

So the visible project was an SSH remote project, but the composer still exposed a Cloud environment selector for an unrelated Cloud repo.

A second sidebar screenshot also showed a Windows local project entry for the same stale project family, e.g. D:\Code\<local-project>, which appears related to the persisted state below.

Local state evidence, sanitized

In %USERPROFILE%\.codex\.codex-global-state.json, the relevant state was inconsistent:

{
  "selected-remote-host-id": "remote-ssh-codex-managed:<remote-host-label>",
  "remote-projects": [
    {
      "id": "<remote-project-id-A>",
      "hostId": "remote-ssh-codex-managed:<remote-host-label>",
      "remotePath": "/Users/<user>/Code/<remote-project>",
      "label": "<remote-project>"
    },
    {
      "id": "<remote-project-id-B>",
      "hostId": "remote-ssh-codex-managed:<remote-host-label>",
      "remotePath": "/Users/<user>/Code/<other-remote-project>",
      "label": "<other-remote-project>"
    }
  ],
  "active-workspace-roots": "D:\\Code\\<local-project>",
  "active-remote-project-id": "<remote-project-id-B>",
  "project-order": [
    "<remote-project-id-A>",
    "D:\\Code\\<local-project>",
    "<remote-project-id-B>",
    "cloud:<owner>/<another-cloud-repo>",
    "cloud:<owner>/<cloud-repo>"
  ],
  "electron-persisted-atom-state": {
    "environment": {
      "label": "<owner>/<cloud-repo>",
      "workspace_dir": "/workspace",
      "repos": ["<cloud-repo-id>"],
      "repo_map": {
        "<cloud-repo-id>": {
          "repository_full_name": "<owner>/<cloud-repo>",
          "default_branch": "main"
        }
      }
    },
    "last-used-continue-in-mode": "cloud"
  }
}

The important mismatch is:

  • selected-remote-host-id points to the SSH remote host
  • remote-projects contains the correct selected remote project
  • active-workspace-roots points to a Windows local project
  • active-remote-project-id points to a different remote project
  • electron-persisted-atom-state.environment still contains a Cloud environment for an unrelated repo
  • The composer follows the stale Cloud environment even while the visible selected project is the SSH remote project

Steps to reproduce

I do not yet have a minimal deterministic repro, but this was observed after using Codex Desktop with all three environment types present:

  1. Configure an SSH remote connection to a Mac host.
  2. Add/open multiple SSH remote projects on that host.
  3. Also have at least one Windows local project saved in Codex Desktop.
  4. Also have Codex Cloud access enabled and a previously selected Cloud environment/repo.
  5. In the Desktop sidebar, select an SSH remote project on the Mac host.
  6. Use the new-chat button/tooltip that says it will start a new chat in that remote project.
  7. Observe the new-chat page: the heading/sidebar/path still refer to the SSH remote project, but the composer environment selector remains bound to the stale Cloud repo.
  8. Inspect %USERPROFILE%\.codex\.codex-global-state.json and observe the mismatched selectors above.

Expected behavior

When the selected project is an SSH remote project:

  • The new-chat composer should target that SSH remote project and host.
  • Any stale Cloud environment selector should be cleared, hidden, or replaced with a remote/local equivalent.
  • active-workspace-roots, active-remote-project-id, selected-remote-host-id, and persisted composer environment state should be reconciled consistently.
  • If Codex cannot reconcile the state, the UI should block the start action or show a clear warning before the user submits a prompt.

Actual behavior

The new-chat screen looked like it was in the selected SSH remote project, but the composer still showed and appeared to retain an unrelated Cloud environment. The local state file also had three conflicting selectors at the same time: SSH remote host selected, Windows local workspace active, and stale Cloud environment persisted.

Workaround attempted

Manually repairing state appears to help only if Codex Desktop is fully quit first. I backed up the state files and cleared the stale Cloud environment / last-used-continue-in-mode, then set the active remote project back to the selected SSH project. Editing while the app is running risks being overwritten by in-memory state.

This points to a startup/runtime reconciliation issue rather than an SSH connectivity issue. The SSH connection itself was green/connected and the remote project path tooltip was correct.

Possible debugging directions

Some areas that may be worth inspecting:

  • Reconciliation between selected-remote-host-id, active-remote-project-id, and active-workspace-roots when opening a new chat from the sidebar
  • Whether electron-persisted-atom-state.environment should be invalidated when the active project source changes from Cloud to SSH remote/local
  • Whether last-used-continue-in-mode = "cloud" is incorrectly reused for a new chat launched from an SSH remote project
  • State restore precedence between .codex-global-state.json, .codex-global-state.json.bak, in-memory Electron/atom state, and app-server state
  • Project identity matching when project-order contains mixed IDs: remote project UUIDs, local filesystem paths, and cloud:<owner>/<repo> entries
  • The new-chat composer should probably derive its environment from the currently selected project, or validate that the persisted composer environment belongs to the same project source before displaying it

Related reports

These may not be exact duplicates, but they look related to stale Desktop project/session/sidebar state and SSH remote project synchronization:

I can provide sanitized screenshots if helpful. The screenshots show the selected SSH remote project and remote path tooltip, while the composer simultaneously shows the unrelated Cloud environment selector.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

When the selected project is an SSH remote project:

  • The new-chat composer should target that SSH remote project and host.
  • Any stale Cloud environment selector should be cleared, hidden, or replaced with a remote/local equivalent.
  • active-workspace-roots, active-remote-project-id, selected-remote-host-id, and persisted composer environment state should be reconciled consistently.
  • If Codex cannot reconcile the state, the UI should block the start action or show a clear warning before the user submits a prompt.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix Codex Desktop new chat in SSH remote project can use stale Cloud/local environment in composer