Long Codex threads fail to hydrate after reload when compacted replacement_history records are large (UI shows empty, logs show missing handler)
What version of the IDE extension are you using?
v26.422.21459
What subscription do you have?
Plus
Which IDE are you using?
VS Code
What platform is your computer?
Linux 6.17.0-22-generic x86_64 x86_64
What issue are you seeing?
A Codex thread remains indexed in VS Code and its session file is valid JSONL, but reopening the thread results in an empty/unhydrated UI.
The thread appears normally in the UI list and is present in workspace state, but no messages are rendered when opened.
Extension logs show repeated:
[IpcClient] Received broadcast but no handler is configured method=thread-stream-state-changed
This suggests a failure in the thread hydration/replay path rather than data loss.
What steps can reproduce the bug?
- Start with a Codex thread that has grown long enough to trigger compaction.
- The session JSONL contains at least one record:
type: "compacted"
with a large "replacement_history" payload.
- Confirm the session file is valid JSONL and the thread is visible in the VS Code UI.
- Reload VS Code (or close and reopen it).
- Open the same Codex thread.
Expected:
- The thread should rehydrate and display prior messages.
Actual:
- The thread opens as an empty/unhydrated UI (no messages displayed).
Additional observation:
- Extension logs repeatedly show:
[IpcClient] Received broadcast but no handler is configured method=thread-stream-state-changed
What is the expected behavior?
Reopening an existing Codex thread should reliably rehydrate and render the full prior conversation history in the UI.
Specifically:
- The thread should display previously exchanged messages.
- Hydration should succeed regardless of thread length or presence of compacted records.
- Stream/state update events (e.g., thread-stream-state-changed) should be handled by the UI layer and result in visible updates.
The presence of compacted records in the session JSONL should not prevent thread replay or rendering.
Additional information
Key observations from local inspection:
- The thread is present and indexed in VS Code workspace state.
- The session file is valid JSONL with no malformed lines.
- The target thread contains a compacted record with a large replacement_history payload (~200 KB).
- Across other sessions, compacted records can reach multi-megabyte sizes and represent a significant portion of total session size (30–40%+ observed).
Logs show repeated warnings:
[IpcClient] Received broadcast but no handler is configured method=thread-stream-state-changed
This suggests that:
- The backend is emitting stream/state updates during hydration,
- But the UI layer is not registering or handling these events.
Hypothesis:
Long-thread replay combined with large compacted payloads may be triggering a failure in the hydration/update path, leaving the UI in an uninitialized state.
Additional note:
The underlying session data appears intact; this is not a data corruption issue but a hydration/rendering failure.
I can assist with further testing (e.g., modified session files with reduced replacement_history payloads) if helpful.
5 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Related issues
This may be related to the following reports describing similar symptoms:
However, this report (#19397) includes additional evidence suggesting a specific failure mode involving large compacted
replacement_historypayloads and missingthread-stream-state-changedhandler during hydration.Additional observation (lifecycle behavior):
Thread hydration appears to be non-deterministic and sensitive to UI lifecycle.
A thread may successfully hydrate on first open after VS Code restart, but fail to rehydrate after navigating away and returning.
Other threads may intermittently recover without changes to their underlying data.
This behavior, combined with repeated log messages:
[IpcClient] Received broadcast but no handler is configured method=thread-stream-state-changed
suggests a race condition where stream/state events are emitted before the UI registers the corresponding handler.
This results in lost hydration events and an empty thread UI.
I faced the same issue. I solved it by making the thread broadcast queue until the handler exists. It worked well so far. Hope that helps.
Additional UI behavior observed:
While hovering over Codex task/session entries in the sidebar, the cursor intermittently flickers between the expected pointer cursor and the default arrow cursor. Occasionally the text briefly blurs and transient drag/drop-style overlay behavior appears, as though the list item is repeatedly entering/leaving a drag or hover state.
This behavior may suggest instability or repeated state changes within the task/session UI layer during hover interaction.
Observed on: