Desktop (ChatGPT.app 26.709): fanout sub-agent threads never registered in renderer — events dropped as "unknown conversation", sessions appear stuck while backend completes

Open 💬 2 comments Opened Jul 13, 2026 by wzyonline-1999

What version of Codex is running?

Codex desktop hosted in ChatGPT.app 26.707.62119 (build 5211), Codex runtime 26.709.11516, bundled codex-cli 0.144.2, macOS 26.0 (arm64)

What subscription do you have?

ChatGPT (logged-in desktop)

What issue are you seeing?

Sub-agent threads spawned by a multi-agent/fanout session are never registered in the desktop renderer. Every event they emit is dropped with Received turn/started|turn/completed|item/started for unknown conversation, so sessions appear permanently stuck ("thinking" spinner) while the backend actually completes all turns. This reproduces on the newest ChatGPT.app-hosted desktop build (26.709), i.e. it is still present after the "Codex joins the ChatGPT desktop app" release.

This looks like the same family as #24475 / #23292 / #31090 / #32502, but I can add database-level evidence that pins the mechanism.

Log fingerprint

~/Library/Logs/com.openai.codex/.../codex-desktop-*.log fills with (≈2,500 lines in one afternoon; each event logged twice — once per renderer window incl. avatarOverlay):

2026-07-13T09:18:40.740Z error [electron-message-handler] Received turn/started for unknown conversation conversationId=019f5ac5-56e4-72b0-8df4-b9e40a5d18e2 rendererWebContentsId=1 ...
2026-07-13T09:18:40.740Z error [electron-message-handler] Received turn/started for unknown conversation conversationId=019f5ac5-56e4-72b0-8df4-b9e40a5d18e2 rendererWebContentsId=2 rendererWindowAppearance=avatarOverlay ...
2026-07-13T09:19:26.896Z error [electron-message-handler] Conversation state not found conversationId=019f5ac5-768f-7280-a4d1-50bc0138ac45 ...

Key detail: the very first event of each such conversationId is already "unknown" — the renderer never knew these threads at any point (it's not a mid-stream desync).

Database evidence (why I'm sure these are fanout sub-agents)

Every "unknown" conversationId maps to a sub-agent thread in ~/.codex/state_5.sqlite:

SELECT source FROM threads WHERE id = '019f5a8d-d462-...';
-- {"subagent":{"thread_spawn":{"parent_thread_id":"019f4ac7-...","depth":1,
--   "agent_path":"/root/overall_session_audit","agent_nickname":"Meitner","agent_role":null}}}

SELECT parent_thread_id, child_thread_id, status FROM thread_spawn_edges
WHERE child_thread_id IN (…all "unknown" ids…);
-- all rows point to the SAME parent session, status=open

The parent is a long-running supervisor-style session (multi-agent fanout). Over ~22h it spawned 135 child threads (2–7/hour, thread_spawn_edges all status=open). Every single one of them is invisible to the renderer; parent turns complete fine in the backend (turn/started: 31, turn/completed: 16 in one log window) while the UI shows stuck spinners.

Repro

  1. ~/.codex/config.toml[features] multi_agent = true, multi_agent_v2 = true, enable_fanout = true
  2. In the desktop app, run a session that spawns sub-agents (fanout audit/research task).
  3. Watch the log: each spawned child's turn/started arrives as unknown conversation; the child never appears in the UI; the parent appears stuck.
  4. Fully restarting the app re-syncs threads that already exist in the DB (previously orphaned children become visible), but every child spawned after the restart is orphaned again — within minutes new unknown conversation spam starts (verified: restarted at 17:11, new spawns at 17:18 were orphaned again).

Expected

Renderer should register spawned sub-agent threads (receive/handle a thread/started for children carrying parent_thread_id) before — or upon — their first event, so their activity is visible and the parent doesn't look hung.

Notes

  • Consistent with the analysis in #24475 (child events arrive before/without parent-side registration). PR #23575 ("async subagent startup for thread spawns") looked like the right direction but was closed unmerged.
  • Single-agent sessions on the same machine are completely unaffected.
  • Backend/network are healthy (all turns complete; results appear after an app restart).

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗