openclaw - 💡(How to fix) Fix [Bug] Session status not updated in sessions.json after turn completion — UI stays running

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…

When a conversation turn completes, the Gateway correctly writes session.ended to the trajectory file, but the status field in sessions.json is NOT updated. As a result, the Control UI continues to show the session as running indefinitely — the Stop button stays red even after the model has finished.

Refreshing the page recovers the correct state because the UI re-queries sessions.list, but without a refresh the stale status persists.

Error Message

11:14:07 [WARN] embedded run agent end 11:14:07 [WARN] context overflow detected; auto-compaction succeeded

Root Cause

Refreshing the page recovers the correct state because the UI re-queries sessions.list, but without a refresh the stale status persists.

Fix Action

Fix / Workaround

Workaround (current)

A /health endpoint in the FastAPI backend auto-detects and fixes stuck running sessions:

  • status === running AND age > 30s AND trajectory contains session.ended → patch sessions.json to done

This is a workaround, not a root-cause fix.

Code Example

{"seq":7,"type":"session.ended","data":{"status":"success",...}}
{"seq":5,"type":"model.completed",...}
{"seq":4,"type":"prompt.submitted",...}current (highest) turn

---

{
  "key": "agent:main:dashboard:5086934c-5e91-4e8c-ba2c-0f6c0e330f0a",
  "sessionId": "b74e20c6-98cf-4355-894f-835d93274132",
  "status": "running",   ← should be done
  "updatedAt": "..."
}

---

11:14:07 [memory-tdai] [agent_end] Auto-capture complete (33ms)
11:14:07 [WARN] embedded run agent end
11:14:07 [WARN] context overflow detected; auto-compaction succeeded
11:14:54 [memory-tdai] [before_prompt_build] Recall complete (8ms)

---

⇄ res ✓ sessions.subscribe 285ms conn=f7671e27...a078 id=75b922f4...9a1b
RAW_BUFFERClick to expand / collapse

Environment

  • OpenClaw version: 2026.5.18
  • Gateway: self-hosted on Ubuntu (Tencent Cloud lightweight server)
  • Protocol: WebSocket RPC (Control UI / WebChat)
  • Session backend: File-based (sessions.json + trajectory JSONL)

Summary

When a conversation turn completes, the Gateway correctly writes session.ended to the trajectory file, but the status field in sessions.json is NOT updated. As a result, the Control UI continues to show the session as running indefinitely — the Stop button stays red even after the model has finished.

Refreshing the page recovers the correct state because the UI re-queries sessions.list, but without a refresh the stale status persists.

Steps to Reproduce

  1. Open Control UI, start a conversation turn
  2. Wait for the model to finish responding (turn completes normally)
  3. Observe: session.ended is written to trajectory, but sessions.json still shows status: running
  4. The Stop button remains red/in-progress indefinitely
  5. Only after page refresh does the UI show the correct status

Expected Behavior

When a turn completes and session.ended is written to the trajectory, the Gateway should also update sessions.json to reflect status: done (or failed/cancelled). The Control UI should receive a sessions.changed broadcast event so it can update in real-time without a page refresh.

Evidence

1. Trajectory shows session.ended, sessions.json shows running

Trajectory (*.trajectory.jsonl) for session b74e20c6-...:

{"seq":7,"type":"session.ended","data":{"status":"success",...}}
{"seq":5,"type":"model.completed",...}
{"seq":4,"type":"prompt.submitted",...}  ← current (highest) turn

sessions.json for the same session:

{
  "key": "agent:main:dashboard:5086934c-5e91-4e8c-ba2c-0f6c0e330f0a",
  "sessionId": "b74e20c6-98cf-4355-894f-835d93274132",
  "status": "running",   ← should be done
  "updatedAt": "..."
}

2. Gateway logs confirm turn completion without status sync

11:14:07 [memory-tdai] [agent_end] Auto-capture complete (33ms)
11:14:07 [WARN] embedded run agent end
11:14:07 [WARN] context overflow detected; auto-compaction succeeded
11:14:54 [memory-tdai] [before_prompt_build] Recall complete (8ms)

Turn completes, session.ended recorded in trajectory, but no sessions.json update appears in logs.

3. Control UI WebSocket receives no push event

WebSocket connection subscribed to sessions.subscribe:

⇄ res ✓ sessions.subscribe 285ms conn=f7671e27...a078 id=75b922f4...9a1b

Throughout the session lifecycle, zero server-pushed events were received (no sessions.changed, no tick, no status update). Only RPC responses to client requests appear.

4. sessions.changed event is defined in protocol

From protocol.md:

sessions.changed: session index or metadata changed.

This event exists in the spec but is apparently not triggered when sessions.json status changes.

Root Cause Hypothesis

The Gateway's run completion handler writes session.ended to the trajectory but does not call the session state write to update sessions.json when status transitions to done. The sessions.changed broadcast is also not fired.

The Control UI may not be calling sessions.subscribe on connect, preventing it from receiving push events even if they were fired.

Impact

  • UI staleness: Stop button shows in progress after turn ends
  • Session accumulation: Stuck running sessions accumulate if auto-fix is not in place
  • Broken UX: Users must manually refresh to see correct session state

Workaround (current)

A /health endpoint in the FastAPI backend auto-detects and fixes stuck running sessions:

  • status === running AND age > 30s AND trajectory contains session.ended → patch sessions.json to done

This is a workaround, not a root-cause fix.

Suggested Fix

  1. Fix session status sync: When a run turn completes, update sessions.json status to done alongside writing session.ended to trajectory.

  2. Fire sessions.changed broadcast: When session metadata (including status) changes, fire sessions.changed so subscribed UI clients can update in real-time.

  3. Auto-subscribe on Control UI connect: Ensure the Control UI calls sessions.subscribe on WebSocket connection so it receives push events.


Related context: OpenClaw Gateway 2026.5.18, self-hosted on Ubuntu, WebSocket RPC protocol v4.

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…

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 - 💡(How to fix) Fix [Bug] Session status not updated in sessions.json after turn completion — UI stays running