Skip to content

[Windows][26.814.5167.0] Hidden avatarOverlay owns completed thread; primary UI stays "Thinking" #39178

Open

Description

@zgl-gits

What version of the Codex App are you using?

  • ChatGPT/Codex Desktop for Windows: 26.814.5167.0
  • Bundled Codex runtime: codex-cli 0.148.0-alpha.15

What platform is your computer?

Windows 11 x64, NT 10.0.26200.

What issue are you seeing?

A local Codex thread finishes successfully in the backend, but the visible primary window remains indefinitely in the Thinking state.

This reproduced twice, including after a full app restart. In both reproductions, the hidden desktop pet / realtime voice renderer (avatarOverlay) resumed the thread first and became the stream owner. The visible primary renderer then became a follower. New turns were actually started by the hidden overlay. After the backend wrote the final answer and task_complete, the primary window did not clear its streaming state.

The affected thread was:

019d80c8-599d-7a02-8b51-7930193b628a

Local state also showed:

  • custom desktop pet selected/awake: custom:railbot
  • realtime voice most-recent thread: the same affected thread
  • the avatarOverlay renderer was created even while rendererWindowVisible=false

What steps can reproduce the bug?

  1. Use Codex Desktop on Windows with a desktop pet / realtime voice overlay configured.
  2. Open an existing local thread that is also recorded as the recent voice thread.
  3. Restart Codex Desktop.
  4. Open the same thread in the visible primary window.
  5. Send a normal prompt.
  6. Wait for the backend to complete.
  7. Observe that the transcript has a final answer and task_complete, and thread APIs report idle, while the visible window continues to show Thinking.

Restarting alone does not resolve the issue because the overlay is recreated and becomes the stream owner again.

Reproduction evidence

Reproduction 1

  • Turn: 01a01420-d20e-7352-a2e1-b8690b1ccb91
  • Local time: 2026-08-18 17:08:10 to 17:11:05 (UTC+08:00)
  • Duration: 174.681 s
  • Result: completed, error=null, transcript contains final answer and task_complete

Desktop log sequence:

avatarOverlay: rendererWindowVisible=false, role=owner
maybe_resume_success: latestTurnStatus=completed, markedStreaming=true
primary renderer: role=follower
turn/start: originWebcontentsId=<hidden avatarOverlay>

Reproduction 2

  • Turn: 01a0142d-b139-7931-b703-b6b4aceac42c
  • Local time: 2026-08-18 17:22:14 to 17:22:41 (UTC+08:00)
  • Duration: 27.348 s
  • Result: completed, error=null, transcript contains final answer and task_complete

The same ownership sequence occurred again:

09:20:34Z hidden avatarOverlay webContentsId=3 -> role=owner
09:20:36Z thread/resume -> latestTurnStatus=completed, markedStreaming=true
09:20:40Z visible primary webContentsId=1 -> role=follower
09:22:14Z turn/start -> originWebcontentsId=3 (hidden avatarOverlay)
after completion, visible primary remained role=follower

There were no authentication failures, 429/5xx responses, model timeouts, stream disconnects, context-limit errors, or backend task failures.

A separate legacy_notify hook emitted Windows os error 206, but the log says after_agent hook failed; continuing, followed by task_complete. This looks secondary and does not explain why the primary renderer consistently becomes a follower.

As a control, a separate diagnostic thread owned directly by the visible primary renderer updated and completed normally.

What is the expected behavior?

  • If latestTurnStatus is completed, failed, or interrupted, resume should not leave the thread marked as streaming.
  • A hidden avatarOverlay should not indefinitely retain stream ownership over a thread displayed in the primary window.
  • The visible primary renderer should receive/reconcile the terminal lifecycle event and immediately clear Thinking.
  • On focus or thread/read, the UI should reconcile against the authoritative backend status (idle) instead of preserving stale follower state.

Additional information

No raw transcript, database, or full logs are attached because they contain private local task data and filesystem paths. Sanitized excerpts and exact timestamps can be provided if maintainers request them.

Related but not identical:

This report was prepared with AI assistance from local diagnostic evidence and submitted with the user's approval.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    sessionIssues involving session (thread) management, resuming, forking, naming, archiving
    on Aug 18, 2026
  2. github-actions commented on Aug 18, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. zgl-gits commented on Aug 18, 2026

    @zgl-gits
    Author

    Workaround / diagnostic update (2026-08-18)

    The affected UI recovered immediately after the user toggled the desktop pet setting off and back on.

    Observed result:

    • The stale Thinking indicator cleared.
    • The affected thread became usable and displayed its completed state normally.
    • No model, reasoning-effort, context-window, session transcript, database, or Codex configuration changes were made.

    This strengthens the hypothesis that the failure is in avatarOverlay stream ownership / renderer-state synchronization. Toggling the pet likely destroys, recreates, or rebinds the overlay and allows the visible primary renderer to reconcile with the authoritative completed/idle backend state.

    This is a confirmed one-time workaround on the affected Windows installation. It has not yet been verified whether the fix survives another full app restart or prevents future recurrence.

  4. Tarrriq commented on Aug 19, 2026

    @Tarrriq

    Workaround / diagnostic update (2026-08-18)

    The affected UI recovered immediately after the user toggled the desktop pet setting off and back on.

    Observed result:

    • The stale Thinking indicator cleared.
    • The affected thread became usable and displayed its completed state normally.
    • No model, reasoning-effort, context-window, session transcript, database, or Codex configuration changes were made.

    This strengthens the hypothesis that the failure is in avatarOverlay stream ownership / renderer-state synchronization. Toggling the pet likely destroys, recreates, or rebinds the overlay and allows the visible primary renderer to reconcile with the authoritative completed/idle backend state.

    This is a confirmed one-time workaround on the affected Windows installation. It has not yet been verified whether the fix survives another full app restart or prevents future recurrence.

    I had the pet off already, turning the pen on and off again solved the problem.
    Thank you

  5. cyphersys commented on Aug 20, 2026

    @cyphersys

    Workaround / diagnostic update (2026-08-18)

    The affected UI recovered immediately after the user toggled the desktop pet setting off and back on.

    Observed result:

    • The stale Thinking indicator cleared.
    • The affected thread became usable and displayed its completed state normally.
    • No model, reasoning-effort, context-window, session transcript, database, or Codex configuration changes were made.

    This strengthens the hypothesis that the failure is in avatarOverlay stream ownership / renderer-state synchronization. Toggling the pet likely destroys, recreates, or rebinds the overlay and allows the visible primary renderer to reconcile with the authoritative completed/idle backend state.

    This is a confirmed one-time workaround on the affected Windows installation. It has not yet been verified whether the fix survives another full app restart or prevents future recurrence.

    I confirm your workaround. Thank you!

  6. itokenchiku commented on Aug 21, 2026

    @itokenchiku

    I can corroborate a closely related Windows Desktop failure involving realtime voice.

    Observed behavior:

    • A delegated child task had already completed and returned its result, but the visible parent thread continued to show Thinking / a running-command indicator indefinitely.
    • While the stale running state was present, starting a realtime voice session also became unavailable or failed to start.
    • Closing and reopening the Codex app did not reliably recover the state.
    • Fully terminating the Codex/ChatGPT process tree in Task Manager, or rebooting Windows, restored normal behavior.
    • This was not caused by the child task's filesystem permission failure; that was a separate scoped sandbox denial, while the stale UI/voice state remained at the app/session layer.

    This matches the hypothesis that a hidden realtime/overlay or background process retains stale stream ownership after the backend work has completed. From the UI alone, it was impossible to distinguish genuine execution from a stale Thinking state.

    Suggested UX/recovery behavior:

    • Reconcile the visible thread with authoritative backend completion state.
    • Clear stale streaming ownership when the backend turn is terminal.
    • Show whether a command is actually running versus only a stale UI state.
    • Provide an in-app recovery action that resets the realtime/overlay session without requiring process-tree termination or a PC reboot.

    No customer data, local paths, transcript content, or credentials are included in this report.

  7. Fireotics commented on Aug 21, 2026

    @Fireotics

    am geting {"detail":"Bad Request"} Error for each Task and wont work.

  8. tobiasbarthold commented on Sep 5, 2026

    @tobiasbarthold

    I can confirm this still reproduces on a newer Codex Desktop build, and I have also observed the same user-visible failure on Debian, so the underlying bug does not appear to be Windows-specific.

    Current Windows reproduction

    • Codex Desktop package: 26.901.5280.0
    • Platform: Windows 11 x64, NT 10.0.26200
    • Reproduced repeatedly after using realtime Voice in an existing local task.

    The task itself was healthy and completed normally. Sanitized evidence from the affected run:

    thread/realtime/stop -> accepted
    hidden avatarOverlay: rendererWindowVisible=false
    visible primary renderer -> role=follower
    new normal turns -> started by the hidden avatarOverlay
    final assistant message -> persisted
    task_complete -> emitted
    thread API -> idle
    visible task UI -> still shows Thinking indefinitely
    

    A minimal verification prompt asked the task to reply with ICH LEBE NOCH. The response was generated and persisted about two seconds later and the turn completed with error=null, but the primary UI never rendered it and continued to show Thinking.

    Local persisted state still pointed realtime-voice-most-recent-thread at the affected task after Voice ended. This matches the stream-ownership diagnosis in the original report: the hidden Voice/avatar overlay retains or reacquires ownership, while the visible task remains a follower and misses terminal reconciliation.

    Debian confirmation

    I have encountered the same post-Voice symptom on Debian as well: backend work completes, but the visible task remains stuck in Thinking and does not display the final response. I do not have the exact Debian build details in this Windows diagnostic session, but the repeated cross-platform reproduction suggests the ownership/reconciliation bug is not specific to the Windows renderer.

    The UI should reconcile from the authoritative terminal/idle thread state after Voice ends, regardless of which renderer previously owned the stream. An explicit in-app “reset Voice/overlay state” recovery action would also help.

    No private transcript, local paths, credentials, or raw session identifiers are included here. This comment was prepared with AI assistance from sanitized local diagnostic evidence and posted at the user's request.

  9. jiadizhunine commented on Sep 6, 2026

    @jiadizhunine

    macOS confirmation: exiting realtime Voice leaves a completed task stuck in Thinking

    I am seeing a closely matching failure on macOS. It happens repeatedly for me after using realtime Voice in an existing local Codex task and then leaving Voice after the task work has finished. One recent occurrence was checked against local desktop logs and the persisted task state.

    Environment

    • ChatGPT/Codex desktop app: 26.901.31953, build 7868
    • App-server reported version: 0.153.1
    • macOS: 27.0, Apple silicon / arm64
    • Observed on September 6, 2026

    Reproduction and user-visible behavior

    1. Open an existing local Codex task.
    2. Start realtime Voice and work with the task.
    3. Once the requested work has finished, exit Voice.
    4. The composer shows an upward-arrow/send-like button instead of the Voice entry button.
    5. The visible task remains in Thinking and does not display the final text response, even though the backend has completed and saved it.

    The repeated frequency is my user observation; the timeline below is one log-verified occurrence. The button appearance by itself is not being treated as proof of the cause.

    Sanitized evidence

    All times below are UTC. Conversation, turn, request, owner-client, and filesystem identifiers have been removed.

    09:38:40.799  thread/realtime/stop accepted, errorCode=null
    09:38:43.255  turn/interrupt accepted, errorCode=null
    09:38:45.353  turn-start configuration resolved in avatarOverlay:
                  rendererWindowVisible=false, rendererWindowFocused=false
    09:38:45.371  turn/start accepted from that hidden overlay, errorCode=null
    09:38:49.501  visible primary renderer: role=owner
    09:38:51.081  visible primary renderer: previousRole=owner -> role=follower
    09:38:55.591  the hidden avatarOverlay receives a completed reasoning-summary item
                  for the affected task and turn
    

    The persisted record for that post-Voice text turn reports:

    • status=completed
    • error=null
    • Duration: approximately 11.1 seconds
    • A final assistant text message is present

    Thus, at least this occurrence was not simply the model taking an indefinitely long time to answer. The backend had a completed response while the visible UI appeared stuck.

    Interpretation and expected behavior

    This is consistent with the hidden Voice/avatar overlay retaining or reacquiring the task's stream handling while the primary window becomes a follower and fails to reconcile completion. That is a working hypothesis, not a confirmed source-level root cause.

    After Voice stops, the visible task should reconcile against the authoritative completed/idle state, display the saved final answer, clear Thinking, and restore consistent composer controls. This macOS observation also appears related to #24217.

    I have not validated the pet-toggle workaround on this Mac, so I cannot report a successful recovery or fix.

    This comment was prepared with AI assistance from local diagnostics and posted with the account owner's authorization. No raw session transcript, project content, private paths, credentials, or full logs are included.

  10. jiadizhunine commented on Sep 7, 2026

    @jiadizhunine

    Follow-up (2026-09-07): two nearly identical ~2-hour Voice disconnects, then a saved final answer missing from the primary UI

    Following my earlier macOS confirmation. I have additional log-verified timing evidence, rather than just the impression that long Voice sessions end unexpectedly.

    Environment

    • Installed ChatGPT/Codex desktop app at this follow-up: 26.901.51231, build 8109.
    • macOS 27.0, Apple silicon / arm64.
    • The incident app-server log reports 0.153.1.
    • The installed desktop version above was checked at diagnosis time; it is not a separately captured version record from the exact disconnect instant. My earlier comment recorded desktop build 7868.

    Two sessions fail at almost exactly the same elapsed time

    All timestamps below are UTC, September 6, 2026. Start means the logged Starting realtime voice transport event; failure means the logged Realtime voice WebRTC connection failed event.

    Session Voice transport start WebRTC failure Elapsed
    A 17:54:21.257 19:54:29.288 7208.031 seconds (2h 8.031s)
    B 21:09:57.515 23:10:05.368 7207.853 seconds (2h 7.853s)

    In both cases, a successful thread/realtime/stop request followed the WebRTC failure. In session B:

    23:10:05.368  Realtime voice WebRTC connection failed
                  rendererWindowAppearance=avatarOverlay
                  rendererWindowVisible=false
    23:10:05.379  thread/realtime/stop response
                  errorCode=null, originWebcontentsId=<overlay>
    

    The user experiences this as Voice exiting automatically after roughly two hours. The matched elapsed times strongly suggest a fixed lifetime/expiry-related trigger, but the logs do not identify a specific maximum-duration setting, token expiry, or server close reason. This is not proof that a two-hour limit is an intentional product policy.

    After the second disconnect, the backend completes but the primary UI does not show its final answer

    For the affected work turn:

    23:07:19      work turn starts while Voice is active
    23:08:38.151  visible primary renderer changes from owner to follower
    23:10:05.368  Voice WebRTC connection fails
    23:10:05.379  realtime stop accepted
    23:29:00.330  hidden avatarOverlay still receives an update for that work turn
    23:30:56.608  final assistant answer persisted
    23:30:56.758  task_complete persisted
    

    A read-only task-state check confirms:

    • thread: idle
    • work turn: completed, error=null
    • duration: 1,417,683 ms (23m 37.683s)
    • final assistant answer: present

    The user's screenshot shows the elapsed 23m 37s, but no final response beneath it. Files and command records confirm that actual work happened; I am not claiming the entire 23 minutes was a frozen UI or that the answer was generated immediately. The confirmed mismatch is that the backend finished and saved its final answer, while the captured primary view did not display it.

    The primary renderer also logs ResizeObserver loop completed with undelivered notifications at 23:30:56.922. This is a coincident diagnostic, not an established cause.

    Questions / expected behavior

    1. Is there an approximately 120-minute realtime call lifetime or expiry/renewal mechanism on this Voice transport? If so, should the client warn, reconnect/renew, or explicitly end the call instead of surfacing only a WebRTC failure?
    2. Regardless of why Voice ends, should the overlay relinquish/reconcile stream ownership so the primary view shows the saved final answer and correct terminal state?
    3. Could maintainers correlate the two UTC failure timestamps with server-side realtime/session-expiry events?

    The public Voice documentation describes plan-dependent usage in rolling five-hour windows; I did not find a stated two-hour per-call lifetime there. Usage allowance and individual call lifetime may be separate issues.

    The fixed-time disconnect and the post-Voice UI reconciliation failure might be separate bugs. I am adding this to the existing issue because the latter matches my earlier report; please advise if the disconnect timing needs a separate linked issue.

    This comment was prepared with AI assistance from local read-only diagnostics and posted with the account owner's authorization. No raw transcripts, project contents, private filesystem paths, credentials, conversation/turn/call IDs, or full logs are attached. No app settings, processes, or project files were changed during this diagnostic.

  11. JeromeZhao-zjx commented on Sep 21, 2026

    @JeromeZhao-zjx

    Confirmed still reproducible on Windows in a newer build.

    Environment

    • OpenAI Codex / ChatGPT Desktop package: 26.915.4065.0 (x64)
    • Desktop renderer build: 9922, commit 0242453bc53bf3fc686ef2bc0f8365b71d9d3900
    • Bundled Codex Doctor/runtime: 0.149.1
    • Platform: Windows x64

    User-visible behavior

    After a completed first turn, the composer accepts follow-up text but the Send control remains disabled. The authoritative thread API reports idle, there is no active rate limit, and the backend state database passes codex doctor health checks.

    Sanitized log sequence (UTC, 2026-09-21)

    05:45:16.856  hidden avatarOverlay (webContentsId=3, visible=false) becomes role=owner
    05:45:16.897  overlay resumes a thread whose latest turn is completed
    05:45:16.919  visible primary renderer changes to role=follower
    05:45:18.899  hidden overlay starts realtime voice for the same completed thread
    05:45:37.475  thread/realtime/stop accepted
    05:45:51.030  hidden overlay starts realtime voice again
    05:46:00.460  second thread/realtime/stop accepted
    05:47:15.982  visible primary renderer is still role=follower
    

    During the same interval the desktop repeatedly logs:

    Received broadcast but no handler is configured method=thread-stream-following-changed
    Received broadcast but no handler is configured method=thread-stream-following-status-requested
    

    This matches the original report closely: a hidden Voice/avatar renderer retains ownership after realtime stop, while the visible primary renderer remains a follower and keeps follow-up sending gated. A full app restart and task reload did not prevent recurrence.

    Expected recovery: after thread/realtime/stop, the overlay should relinquish ownership and the focused primary renderer should reconcile against the terminal/idle backend state. The app should also expose an explicit reset/recovery action for a stale Voice/overlay session.

    No transcript content, local paths, account data, credentials, raw logs, or thread/call identifiers are included. This comment was prepared from sanitized local diagnostics at the user's request.

  12. Maguro-Tsukiji commented on Sep 21, 2026

    @Maguro-Tsukiji

    I can reproduce a related Windows Desktop failure in an existing local Codex task where a hidden avatarOverlay renderer takes stream ownership and prevents the primary composer from submitting a follow-up.

    Environment

    • OS: Windows 11 x64
    • ChatGPT/Codex Desktop package: 26.915.31945
    • Desktop renderer build: 9922, commit 0242453bc53bf3fc686ef2bc0f8365b71d9d3900
    • Affected surface: existing local Codex task (not a new chat)

    User-visible behavior

    1. Open an existing local Codex task with a completed turn.
    2. The composer accepts a follow-up message and exposes Send.
    3. Clicking Send does not start a new turn; the message remains unsent.
    4. A normal app restart did not resolve the issue.

    Sanitized diagnostic sequence

    All timestamps are UTC. Conversation, request, owner-client, project, and local-path identifiers have been removed.

    13:34:07.195  hidden avatarOverlay (renderer 3, visible=false) logs:
                  Conversation state not found
    13:34:08.126  same hidden avatarOverlay becomes stream role=owner
    13:34:08.530  overlay thread/resume succeeds
    13:34:08.532  visible primary renderer logs:
                  Conversation state not found
    13:38:56.348  Settings > Connections > “Control this PC” is disabled;
                  remoteControl/disable is accepted for both renderers
    13:39:48.554  visible primary renderer is still assigned role=follower
    13:40:50.288  after the hidden overlay renderer is terminated, the visible
                  primary renderer becomes role=owner
    13:41:25.412  the previously unsent follow-up succeeds: turn/start accepted
                  from the primary renderer (errorCode=null)
    

    Disabling Remote Control alone did not immediately restore primary ownership; it only removed one possible trigger. The recovery was observed after the hidden overlay renderer was gone and the primary renderer regained owner.

    Interpretation

    This is consistent with an invisible avatarOverlay retaining or acquiring stream ownership for an existing task after a conversation-state hydration failure. The primary renderer then remains a follower and the composer cannot submit a normal follow-up, despite the thread being otherwise resumable.

    This is a working hypothesis based on logs, not a source-level root-cause claim.

    Expected behavior

    • A hidden overlay must not retain ownership of a normal text task after resume/hydration fails.
    • The focused primary renderer should reconcile ownership and re-enable normal submission automatically.
    • The desktop app should provide a safe in-app recovery action to reset/rebind a stale Voice/avatar overlay, rather than requiring process/window termination.

    No transcript content, credentials, account identifiers, raw thread IDs, project names, or local filesystem paths are included. This report was prepared from sanitized local diagnostics and posted with the account owner's authorization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingpetssessionIssues involving session (thread) management, resuming, forking, naming, archivingwindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions