Codex Desktop Remote: re-enrollment leaves existing threads assigned to the old host/project, causing “New chat” and a blank screen
App version
- ChatGPT/Codex Desktop:
26.803.41515(build6321) - Bundled Codex CLI:
codex-cli 0.147.0-alpha.6.5 - Remote Windows app-server:
0.147.0-alpha.6.5
Subscription
pro20X
Platforms
Controller:
Darwin 25.6.0 arm64 arm
macOS 26.6 (25G72)
Remote host:
Windows 11 Pro 25H2
Same physical Windows machine before and after re-enrollment
Time zone used for the timestamps below:
Asia/Tokyo (UTC+09:00)
Summary
After removing an unavailable Remote connection and re-enrolling the same physical Windows machine, Codex Desktop created a new Remote environment ID and a new project ID for the same remote project.
Creating a new enrollment ID may be expected for security. The bug is that dependent task/project state was only partially migrated:
- the existing thread is enumerated under the new host;
thread/readthrough the new host succeeds and returns the original title, remote working directory, and history;- the persisted
thread-project-assignmentsentry still points to the old host ID and old project ID; - the same remote project path exists as a second project under the new host;
- the thread is consequently returned with
projectId: null; - the macOS UI falls back to “New chat” and opens a blank, apparently frozen screen.
The remote thread data and project files still exist. This is an apparent-loss/UI-continuity failure rather than confirmed data loss.
Steps to reproduce
- Pair Codex Desktop on macOS with a Windows machine through Remote Control.
- Add a remote project on that machine and create or continue one or more threads in the project.
- Turn off the Windows machine so the macOS client repeatedly attempts to reconnect.
- Remove/disconnect the unavailable Remote host from the macOS client.
- Turn on the same Windows machine later and enroll/add it again.
- Observe that the re-enrolled machine has a new Remote environment ID.
- Observe that the same remote project is represented by a new project ID.
- Open an existing thread that was created under the old enrollment.
- The task title appears as “New chat”.
- Selecting it opens a blank screen and the task cannot be continued from the UI.
Expected behavior
A newly issued enrollment ID may represent a new authorization generation, but it should not invalidate durable project and thread identity.
After re-enrolling the same host, Codex should do one of the following:
- safely and atomically migrate the existing project/thread associations to the new enrollment;
- retain an old-to-new host alias and resolve stale assignments;
- prompt the user to relink the old project and threads to the newly enrolled host;
- at minimum, open the thread history read-only and show an actionable recovery message.
The UI should not display “New chat” when the server still has the real title, and it should never remain blank without an error or recovery action.
The official Remote documentation says a connected computer provides access to the same projects and chats, and that sleep or network loss should only make Remote temporarily unavailable:
https://learn.chatgpt.com/docs/remote-connections
Actual behavior and state mismatch
All identifiers and paths below are placeholders; no real account, host, project, thread, or filesystem identifiers are included.
OLD_HOST = <OLD_REMOTE_ENV_ID>
NEW_HOST = <NEW_REMOTE_ENV_ID>
OLD_PROJECT = <OLD_PROJECT_ID>
NEW_PROJECT = <NEW_PROJECT_ID>
REMOTE_PATH = <REMOTE_PROJECT_PATH>
THREAD = <AFFECTED_THREAD_ID>
The persisted relationship is effectively:
selected remote host
-> NEW_HOST
remote project for the current connection
-> NEW_PROJECT / NEW_HOST / same remote path
thread-project-assignments[THREAD]
-> OLD_PROJECT / OLD_HOST / same remote path
thread enumeration/read
-> THREAD / NEW_HOST / projectId=null
This creates a partially migrated state:
thread summary/read -> new host
project assignment -> old host
filesystem path -> same remote project
UI hydration -> “New chat” / blank screen
Diagnostic timeline
All timestamps below are shown in Asia/Tokyo (UTC+09:00).
Old connection removal
At approximately 2026-08-09 10:45:34 +09:00, the old Remote manager was removed:
source=registry_delete_manager
hostId=<OLD_REMOTE_ENV_ID>
state=disconnected
Old selection reconciled to the new host
At 2026-08-10 10:16:46 +09:00, Codex logged one available connection and reconciled the persisted old host to the new host:
persistedSelectedRemoteHostId=<OLD_REMOTE_ENV_ID>
selectedRemoteHostId=<NEW_REMOTE_ENV_ID>
availableConnectionCount=1
Startup routing race and wrong filesystem routing
At 2026-08-10 15:00:34 +09:00, startup briefly attempted to use the new host before its request client was registered:
No AppServerRequestClient registered for hostId: <NEW_REMOTE_ENV_ID>
The local macOS git watcher then attempted to watch the remote Windows project path as a local workspace root:
Failed to watch workspace root for git init
cwd=<REMOTE_PROJECT_PATH>
errorCode=ENOENT
The Remote websocket subsequently connected successfully.
Thread body remains readable
At 2026-08-10 15:14:49 +09:00, a direct read through the new host succeeded:
method=thread/read
conversationId=<AFFECTED_THREAD_ID>
errorCode=null
durationMs=886
A second direct read also succeeded in approximately 5.6 seconds.
The response contained:
- the original non-placeholder title;
- the correct remote working directory;
- the existing task history;
hasMore=true;- no thread error.
Therefore, the thread body is not missing or structurally corrupt. The visible “New chat” title appears to be a client fallback/loading placeholder.
Additional observations
- There is only one summary for the affected thread.
parentThreadIdis null; no parent/child cycle was found.- No duplicate conversation ID was found.
- Relevant SQLite integrity checks succeeded.
- No application crash report was generated; the failure manifests as a blank/unresponsive renderer state.
- Multiple existing remote thread assignments remained bound to the old host, so this does not appear to be isolated corruption of one thread.
- The affected thread is relatively large. A recent page returned about 260 KB and many render items. This might amplify blank-screen rendering, but it does not explain the stale host/project assignment.
User impact
- Existing tasks appear to have been deleted or renamed to “New chat”.
- Users may reasonably believe remote files or task history were lost.
- The affected task cannot be continued through the Desktop UI even though the backend still serves it.
- Users may attempt destructive recovery actions such as deleting local state, re-adding projects repeatedly, reinstalling the app, or recreating work that still exists.
- Project/task continuity breaks when an enrollment ID rotates.
Suggested fix
Please consider separating durable logical identities from revocable enrollment identities:
- Keep a stable logical host identity independent of the current enrollment ID.
- Associate projects with the logical host and a stable project/root identity.
- Treat the enrollment/environment ID as a replaceable transport/authorization generation.
- When an enrollment is replaced, atomically migrate or invalidate:
- selected remote host;
- remote project endpoint;
- thread-to-project assignments;
- workspace-root hints;
- auto-connect state;
- persisted run-location state.
- If the app cannot safely prove that the new enrollment is the same logical host, show an explicit “Relink this project/task to the newly connected host” workflow.
- If a thread can be read but its project assignment is stale, open its history in a safe projectless/read-only mode instead of showing a blank screen.
- Never send a remote Windows path to a local macOS filesystem watcher.
- Display an actionable error instead of the generic “New chat” placeholder.
Related issues
- https://github.com/openai/codex/issues/25250
- https://github.com/openai/codex/issues/35167
- https://github.com/openai/codex/issues/24024
Privacy
This report intentionally contains no account identity, email address, host name, IP address, physical location, geographic claim, real filesystem path, project name, thread title, source code, or complete thread/environment/project identifier.
Exact identifiers and narrowly filtered diagnostic excerpts can be provided privately through Codex in-app feedback if requested. No raw global-state file, complete transcript, authentication file, token, pairing code, or unfiltered log is attached.
1 Comment
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action