openclaw - ✅(Solved) Fix TUI can stay stuck in streaming state after reply is finished [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#62395Fetched 2026-04-08 03:04:55
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Participants
Timeline (top)
cross-referenced ×1

After a long troubleshooting session, the TUI kept showing the assistant as "streaming" long after the visible reply had already completed. Restarting the gateway sometimes cleared it temporarily, but the indicator returned, so restart appears to mask the symptom rather than fix the root cause.

Error Message

  • TUI still shows the assistant/session as streaming after the reply is visibly done
  • This persists long after typing/output has stopped
  • Restarting the gateway can temporarily clear it
  • The symptom can return later
  • At the time of investigation:
    • no meaningful active background exec remained
    • no active subagents remained
    • completed debug commands had already exited
    • an old linked ACP child session reference was still present in parent metadata

Root Cause

After a long troubleshooting session, the TUI kept showing the assistant as "streaming" long after the visible reply had already completed. Restarting the gateway sometimes cleared it temporarily, but the indicator returned, so restart appears to mask the symptom rather than fix the root cause.

PR fix notes

PR #62602: fix:(tui) reset stale streaming state after event gaps

Description (problem / solution / changelog)

Summary

Describe the problem and fix in 2–5 bullets:

If this PR fixes a plugin beta-release blocker, title it fix(<plugin-id>): beta blocker - <summary> and link the matching Beta blocker: <plugin-name> - <summary> issue labeled beta-blocker. Contributors cannot label PRs, so the title is the PR-side signal for maintainers and automation.

  • Problem: TUI could stay stuck in streaming after a run effectively ended when a gateway event gap/desync happened.
  • Why it matters: the status line looked busy indefinitely and stale activeChatRunId could block clean progress to the next run.
  • What changed: added explicit TUI gap-reset handling to clear stale active run state and wired it into client.onGap (with reload) and client.onDisconnected (no reload).
  • What did NOT change (scope boundary): no protocol/gateway contract changes, no plugin/channel behavior changes, no config/schema changes.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #62395
  • Related #
  • This PR fixes a bug or regression

Root Cause (if applicable)

For bug fixes or regressions, explain why this happened, not just what changed. Otherwise write N/A. If the cause is unclear, write Unknown.

  • Root cause: event-gap recovery did not clear stale activeChatRunId / streaming state in the TUI state machine.
  • Missing detection / guardrail: no gap-specific reset path test to assert transition back to idle and acceptance of a fresh run.
  • Contributing context (if known): TUI relied on normal final/aborted/error chat events for cleanup, but gap/desync can skip those events.

Regression Test Plan (if applicable)

For bug fixes or regressions, name the smallest reliable test coverage that should catch this. Otherwise write N/A.

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
    • Target test or file: src/tui/tui-event-handlers.test.ts
    • Scenario the test should lock in: a stream receives delta, then a gap reset occurs, state returns to idle, stale run is cleared, and next run streams normally.
    • Why this is the smallest reliable guardrail: the bug is TUI state-transition logic in event handlers; unit coverage is direct and deterministic.
    • Existing test that already covers this (if any): none specific to gap reset prior to this.
    • If no new test is added, why not: N/A (new tests added).

User-visible / Behavior Changes

List user-visible changes (including defaults/config).
If none, write None.

  • TUI now recovers to idle after an event gap instead of potentially remaining stuck in streaming.
  • After a gap reset, subsequent runs can become the active stream normally.

Diagram (if applicable)

For UI changes or non-trivial logic flows, include a small ASCII diagram reviewers can scan quickly. Otherwise write N/A.

Before: [event gap during stream] -> [stale activeChatRunId remains] -> [status can stay "streaming"]

After: [event gap during stream] -> [handleEventGap clears stale run + sets idle] -> [history refresh] -> [next run streams normally]

Security Impact (required)

  • New permissions/capabilities? (Yes/No): No
  • Secrets/tokens handling changed? (Yes/No): No
  • New/changed network calls? (Yes/No): No
  • Command/tool execution surface changed? (Yes/No): No
  • Data access scope changed? (Yes/No): No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS (local dev machine)
  • Runtime/container: Node v25.5.0, pnpm
  • Model/provider: N/A
  • Integration/channel (if any): TUI + gateway chat event stream
  • Relevant config (redacted): default local dev config

Steps

  1. Start TUI and begin a chat stream (delta events).
  2. Trigger/observe an event-gap/desync path.
  3. Check activity state and ability to continue with a new run.

Expected

  • Activity returns to idle after gap recovery.
  • Stale active run is cleared.
  • New run can stream normally.

Actual

  • Added and passed unit tests confirming gap reset and non-regression for active streams.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: ran targeted test files manually:
    • pnpm test src/tui/tui-event-handlers.test.ts (24 passed)
    • pnpm test src/tui/tui.test.ts (27 passed)
  • Edge cases checked: gap reset clears stale run; ongoing valid stream is not cleared.
  • What you did not verify: full repo test matrix; manual interactive end-to-end gap reproduction in live TUI session.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No): Yes
  • Config/env changes? (Yes/No): No
  • Migration needed? (Yes/No): No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: gap handling may clear an active run aggressively in borderline transient conditions.
  • Mitigation: scoped reset only on explicit onGap/disconnect paths plus regression tests for normal active-stream continuity.

Built with Codex

Changed files

  • src/tui/tui-command-handlers.test.ts (modified, +6/-3)
  • src/tui/tui-command-handlers.ts (modified, +2/-0)
  • src/tui/tui-event-handlers.test.ts (modified, +279/-0)
  • src/tui/tui-event-handlers.ts (modified, +54/-3)
  • src/tui/tui.ts (modified, +20/-16)
RAW_BUFFERClick to expand / collapse

Summary

After a long troubleshooting session, the TUI kept showing the assistant as "streaming" long after the visible reply had already completed. Restarting the gateway sometimes cleared it temporarily, but the indicator returned, so restart appears to mask the symptom rather than fix the root cause.

Environment

  • OpenClaw: 2026.4.5
  • Model: openai-codex/gpt-5.4
  • Surface: openclaw-tui / direct session

Context / trigger

This showed up during a long session that included:

  • plugin install and config changes
  • gateway restarts
  • channel debugging
  • WeChat (openclaw-weixin) setup and verification
  • a previously linked ACP child session still appearing in parent metadata

The WeChat setup was eventually successful, so the stuck streaming symptom appears to be separate from final channel health.

Steps to reproduce

Not yet reduced to a minimal repro, but the symptom appeared after a long live session with:

  1. multiple tool calls
  2. several exec diagnostics
  3. gateway restarts
  4. plugin/channel setup
  5. continued chatting in the same session

Observed behavior

  • TUI still shows the assistant/session as streaming after the reply is visibly done
  • This persists long after typing/output has stopped
  • Restarting the gateway can temporarily clear it
  • The symptom can return later
  • At the time of investigation:
    • no meaningful active background exec remained
    • no active subagents remained
    • completed debug commands had already exited
    • an old linked ACP child session reference was still present in parent metadata

Expected behavior

Once the assistant reply is complete and there is no active task still producing output, the TUI should stop showing the session as streaming.

What was ruled out

  • Not simply an active WeChat setup task
  • Not explained solely by lingering debug exec commands
  • Not explained by active subagents
  • Not fixed permanently by gateway restart

Likely cause / hypothesis

A TUI or session-state bug, possibly caused by one of:

  • stale running/streaming state in the parent session
  • stale child-session metadata, especially an old linked ACP child
  • queue/session lifecycle state not being cleared cleanly after complex tool-driven turns
  • UI treating session state too literally after prior activity

Extra clue

A stale linked child ACP session remained visible in the parent session metadata:

  • agent:codex:acp:a542397c-a6f3-419c-a4f2-f758f263632c

This did not appear to be an actively running worker, but it may still be relevant to how the TUI decides the session is "streaming".

Impact

  • misleading UI state
  • makes it look like the assistant is still busy or hung
  • reduces trust in whether the system is actually idle

extent analysis

TL;DR

The most likely fix or workaround involves clearing stale session-state data, particularly the old linked ACP child session metadata, to resolve the TUI's incorrect "streaming" indicator.

Guidance

  • Investigate and clear any stale running/streaming state in the parent session to ensure it accurately reflects the current activity status.
  • Remove the old linked ACP child session reference (agent:codex:acp:a542397c-a6f3-419c-a4f2-f758f263632c) from the parent session metadata to prevent it from influencing the TUI's session state assessment.
  • Review the queue and session lifecycle management to ensure that states are being cleared cleanly after complex tool-driven interactions, which might involve adjusting how the system handles the completion of tasks and updates the UI accordingly.
  • Temporarily, try manually resetting or clearing the session state through available commands or interfaces, if such options exist, to see if this resolves the "streaming" indicator issue.

Example

No specific code snippet is provided due to the lack of direct code references in the issue, but any solution would likely involve modifying how session states are managed and updated in the codebase.

Notes

The exact steps to fix the issue may require further investigation into the system's internals, especially how session states are tracked and updated. The presence of a stale child session reference in the parent metadata is a strong clue but may not be the sole cause.

Recommendation

Apply a workaround by manually clearing stale session-state data and removing old child session references from parent metadata, as this directly addresses the likely cause without requiring a code change or version upgrade, which may not be immediately available or verified to fix this specific issue.

FAIL-SAFE

Given the information, focusing on clearing stale data and ensuring proper session state management is a safe and reasonable approach to mitigate the symptom without introducing potential regressions or destabilizing the system further.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Once the assistant reply is complete and there is no active task still producing output, the TUI should stop showing the session as streaming.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix TUI can stay stuck in streaming state after reply is finished [1 pull requests, 1 participants]