Desktop renderer can show raw {"detail":"Unsupported content type"} after patch-only turn and stream-state desync

Open 💬 3 comments Opened Jun 23, 2026 by astelmach01

Summary

Codex Desktop displayed a raw error pill:

{"detail":"Unsupported content type"}

after a successful patch-only turn. The turn itself completed and the patch operations succeeded. Local evidence points to a Desktop renderer thread-state synchronization failure, not a CLI failure or a model/backend sampling failure.

PII scrubbed: local usernames, account IDs, email addresses, exact home paths, private repo names, and private task identifiers are omitted or generalized.

Environment

  • App: Codex Desktop
  • Bundled Codex CLI: 0.142.0-alpha.1
  • Shell/PATH Codex CLI: 0.141.0
  • Platform: macOS arm64
  • Originator in rollout metadata: Codex Desktop

What Happened

  1. A turn performed only file edits via apply_patch.
  2. The rollout recorded three successful patch calls.
  3. The rollout then recorded task_complete with last_agent_message: null.
  4. The Desktop UI showed the patch summary card, followed by a raw error pill containing {"detail":"Unsupported content type"}.
  5. On the next interaction, Electron logs showed renderer state-sync failures for the same conversation:
  • Item not found in turn state itemId=...
  • Failed to apply patches for conversationId=... errorMessage="[Immer] minified error nr: 18..."

Evidence

The persisted rollout shows the patch-only turn completed successfully:

response_item custom_tool_call apply_patch status=completed
patch_apply_end success=true
response_item custom_tool_call_output
...
event_msg task_complete last_agent_message=null

The Electron Desktop log then shows the renderer losing incremental turn state:

error [electron-message-handler] Item not found in turn state itemId=<tool-call-id>
warning [electron-message-handler] Failed to apply patches for conversationId=<conversation-id> errorMessage="[Immer] minified error nr: 18..."

The bundled renderer code path applies follower patches and only logs on failure:

handleThreadStreamStateChanged(...) {
  ...
  let conversation = this.params.threadStore.getConversation(conversationId);
  if (conversation) try {
    let next = applyPatches(conversation, change.patches);
    this.params.threadStore.setConversation(next);
    ...
  } catch (error) {
    logger.warning(`Failed to apply patches for`, ...)
  }
}

Ruled Out

  • codex --help works with both PATH CLI and bundled Desktop CLI.
  • codex doctor reports no content-type or app-server failure; only terminal TERM=dumb is flagged in this shell context.
  • The model sampling request around the later observed recurrence completed with HTTP 200 in core logs.
  • Searching the OSS source and bundled app assets did not find Unsupported content type as a hardcoded Desktop string, which suggests it is a surfaced response body rather than frontend copy.

Expected Behavior

A successful patch-only turn should render as completed without a raw JSON error pill. If a renderer follower falls out of sync, Desktop should recover by requesting or broadcasting a full conversation snapshot instead of leaving the UI in a partial/error state.

Actual Behavior

The UI showed a raw backend-style JSON body as a transcript error after the successful patch summary. Subsequent logs show renderer follower patch application failures for missing turn items and an Immer patch failure.

Suggested Fix Direction

  • On thread-stream-state-changed patch application failure, fall back to a full snapshot/resync for that conversation.
  • Avoid rendering raw JSON response bodies such as {"detail":"..."} directly as transcript/system-error content when the error is renderer-local or bridge-local.
  • Consider a regression test for a patch-only turn where no final assistant message exists and a follower client receives incremental patches out of order or against stale turn state.

Repro Notes

I could not reproduce via CLI-only commands; the issue appears Desktop-specific and tied to multiple renderer/client stream synchronization. The local app process had multiple renderer processes plus the app-server sidecar active when the error occurred.

View original on GitHub ↗

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