Skip to content

Codex Desktop mislabels automatic WebRTC failure cleanup as user-ended realtime session #35201

Open

Description

@clairernovotny

Summary

When a Codex Desktop realtime voice WebRTC connection fails, the client automatically stops the session, but the backend/transcript-tail handoff reports that the user ended it.

Environment

  • Codex Desktop 26.721.31836 (build 5828)
  • Bundled app-server 0.146.0-alpha.3.1
  • macOS 27.0 (26A5388g), Apple silicon

Reproduction / observed timeline

All times are EDT on 2026-07-24:

  1. 10:29:31.957 — a realtime voice session started.
  2. 10:38:29.636 — the desktop renderer logged Realtime voice WebRTC connection failed.
  3. 10:38:29.640 — four milliseconds later, the same renderer called thread/realtime/stop.
  4. The later transcript-tail handoff reported that the user had ended the session.
  5. 10:40:46.759 — the still-running app started another realtime voice session successfully.

Local corroboration (home-relative paths only):

  • ~/Library/Logs/com.openai.codex/2026/07/24/codex-desktop-…log, lines 14085–14101: session start and ID; line 15313: WebRTC failure; line 15314: automatic stop; lines 15608–15621: successful restart in the same app.
  • ~/.codex/logs_2.sqlite: RealtimeConversationClose has no client_user_message_id.
  • An earlier identical WebRTC failure was followed by source=transcript_tail_flush with “The user just ended their realtime session.”

The affected app did not restart or crash; there was no sleep/wake event or session-limit indication. The exact ICE/network subcause was not logged.

Expected behavior

An automatic WebRTC failure cleanup should be reported as connection_lost / webrtc_failed, not as user intent. The transcript tail should still be flushed once, and the UI should offer or attempt reconnection.

Likely cause

The client distinguishes the WebRTC failure path internally, but that end reason is lost or ignored by the server-facing stop/finalization path. Tail flushing is generic session cleanup, so it must not imply a user-requested stop.

Relevant code:

Suggested fix

Carry a required end reason through stop and transcript finalization, e.g. user_requested, webrtc_failed, inactivity, app_unmounted, and server_closed.

For webrtc_failed, preserve the transcript tail but use neutral connection_lost wording. Record the WebRTC/ICE state and end reason without transcript content, and add a bounded reconnect grace period where feasible.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    app-serverIssues involving app server protocol or interfaces
    connectivityIssues involving networking or endpoint connectivity problems (disconnections)
    on Jul 24, 2026
  2. rohanpatel2002 commented on Jul 24, 2026

    @rohanpatel2002

    Analysis (OSS verification)

    Confirmed this is partly fixable in openai/codex (app-server/core), with a required Desktop call-site change.

    What I verified

    • thread/realtime/stop params are only { threadId } — no end reason (ThreadRealtimeStopParams in app-server-protocol/.../realtime.rs).
    • Stop is submitted as generic Op::RealtimeConversationClose, which ends as RealtimeConversationEnd::Requested.
    • Transcript-tail flush always uses the hard-coded instruction: "The user just ended their realtime session..." (REALTIME_SESSION_ENDED_HANDOFF_INSTRUCTION in core/src/realtime_conversation.rs), including for source=transcript_tail_flush.
    • Close notifications already distinguish requested / transport_closed / error, but that distinction is not carried into the handoff wording, and Desktop auto-stop currently looks like a user request.

    Suggested direction

    1. Add an explicit end reason to thread/realtime/stop (experimental), g. user_requested, webrtc_failed, transport_closed, error, server_closed.
    2. Thread that reason through close + transcript-tail flush; keep flushing the tail, but use neutral connection_lost wording for non-user reasons.
    3. Desktop must pass webrtc_failed (or equivalent) on automatic WebRTC cleanup instead of a bare stop.

    Happy to refine once a maintainer confirms the intended reason enum / wording.

  3. mmnm commented on Sep 8, 2026

    @mmnm

    Additional observation on macOS, September 7, 2026, submitted at the request of the affected user.

    Environment: macOS 26.6.2 (25G83). The nearby desktop renderer log reports release 26.901.51231; the app bundle version was not independently retrieved.

    Observed sequence in local desktop logs:

    1. A realtime voice session started normally.
    2. Approximately 2 hours and 6 seconds later, the renderer logged Realtime voice WebRTC connection failed for that session.
    3. About 8 ms later, the app-server recorded a thread/realtime/stop response with no application error code.
    4. The subsequent handoff described the session as user-ended, while the user reported an unexpected termination and asked what happened.
    5. Text conversation remained available, and a later voice session could start in the same task.

    This independently corroborates the misleading end-reason symptom described in this issue. It does NOT establish the underlying network/ICE cause or a two-hour session limit. This is one observed event, not a controlled reproduction. No assistant end-call action was issued in the affected conversation.

    Expected: preserve the conversation, identify unexpected connection loss accurately, and offer a clear recovery/reconnect action instead of attributing the stop to user intent. If an intentional duration limit applies, explain it and provide a graceful continuation path.

    Privacy: only sanitized diagnostic facts are included. No transcript, project content, account details, local paths, session/task identifiers, screenshots, credentials, or raw log files are attached.

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 appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingconnectivityIssues involving networking or endpoint connectivity problems (disconnections)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions