Skip to content

[macOS] Opening local threads waits 5s for thread-owner-discovery timeout #37397

Description

@yeliex

What version of the Codex App are you using?

ChatGPT/Codex Desktop 26.803.41515 (build 6321)

Bundled app-server: 0.147.0-alpha.6.5

What platform is your computer?

  • macOS 27.0 (26A5388g)
  • Apple Silicon / arm64

What issue are you seeing?

After updating the desktop app, opening an existing local thread consistently takes about five seconds longer than before.

The delay is not in session parsing, thread/read, MCP startup, or a remote-environment handshake. It occurs before thread/read, while Desktop synchronously performs owner discovery for followExistingOwner.

The observed path in the packaged app is:

maybe_resume_started
  -> clientCoordination.findThreadOwner()
  -> local IPC request: thread-owner-discovery
  -> 5000 ms timeout
  -> maybe_resume_owner_discovery_failed (Error: timeout)
  -> thread/read

Desktop catches the timeout and continues, so the thread eventually loads, but every cold resume pays the full timeout.

Reproduction

  1. Start Codex Desktop.
  2. Open an existing local thread that is not already hydrated in the current renderer.
  3. Observe an approximately five-second loading delay.
  4. Repeat with other local threads.

In 12 sampled cold resumes, owner discovery failed after approximately 5001-5066 ms. Once the timeout fired:

  • thread/read started about 5-17 ms later.
  • thread/read itself completed in approximately 3-7 ms.

Representative sanitized log sequence:

07:18:43.775 maybe_resume_started
                 hostId=local
                 previousResumeState=needs_resume
                 previousStreamRole=null

07:18:48.777 maybe_resume_owner_discovery_failed
                 hostId=local
                 errorName=Error
                 errorMessage=timeout

The duration is 5002 ms.

Source-level correlation

Inspection of the packaged Desktop JavaScript shows that thread hydration is invoked with followExistingOwner: true.

Before starting hydration / thread/read, Desktop awaits:

clientCoordination.findThreadOwner({ hostId, conversationId })

For a local host, this sends a thread-owner-discovery IPC request with a 5000 ms timeout. The timeout appears to be a watchdog, not an intentional sleep: owner discovery should normally return quickly when all local clients answer.

The IPC router asks the other connected Desktop clients whether they can handle the request. If there is no current owner, all clients need to answer negatively. At least one connected client appears not to answer, so discovery waits until the watchdog expires.

Isolation performed

  • The affected host is hostId=local.
  • The request uses Desktop's local Unix-domain IPC socket under ~/.codex/ipc/; it is not an Internet/proxy/TUN request.
  • No MCP server startup occurs inside the five-second interval.
  • Plugin listing may run concurrently, but it completes before the owner-discovery timeout.
  • Session reading is fast after the timeout.
  • Removing the Popout Window hotkey did not change the behavior.
  • In a fresh-launch sample, the timeout occurred before hotkeyWindowHome and hotkeyWindowThread were created, ruling those windows out as the direct trigger.
  • Fully restarting Desktop with a newly created IPC socket still reproduces the problem.

The fresh-launch window timeline was:

07:18:40.800 primary routes mounted
07:18:41.740 hidden avatarOverlay main frame loaded
07:18:43.767 hidden avatarOverlay routes mounted
07:18:43.775 maybe_resume_started
07:18:48.777 owner discovery timeout
07:18:52.921 hotkeyWindowHome loaded
07:18:53.204 hotkeyWindowThread loaded

The persisted pet visibility state was already false, but Desktop still prewarmed a hidden avatarOverlay renderer. This makes that renderer a plausible non-responsive discovery client, but the current logs do not include enough client identity information to prove which IPC client failed to answer.

The same Desktop session also records IPC lifecycle warnings such as write EPIPE, ipc-connection-reset, and broadcasts received without registered handlers. These may be related to a stale or partially initialized renderer client.

Expected behavior

Opening a local thread should not block for the full owner-discovery watchdog.

If no other live window owns the thread, owner discovery should resolve immediately and hydration should proceed.

Suggested fix areas

  • Exclude non-thread surfaces such as avatarOverlay, browser surfaces, or other hidden/prewarmed renderers from thread-owner discovery.
  • Ensure every registered IPC client answers discovery with canHandle: false when it cannot own a thread.
  • Remove stale clients promptly when a renderer/window is destroyed or reset.
  • Fail owner discovery fast when a client has no relevant handler.
  • Avoid serially blocking thread/read on the full five-second watchdog.
  • Include client ID and window appearance in owner-discovery timeout diagnostics so the non-responsive client can be identified.

I can provide a narrowly sanitized log window or additional timing samples if useful. Raw logs and thread IDs are omitted for privacy.

Registered via Codex Papercuts skill

Metadata

Metadata

Assignees

Labels

Papercuts 2026appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingperformance

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions