Skip to content

fix(gateway): never return an empty chat.history transcript#92383

Merged
clawsweeper[bot] merged 2 commits into
openclaw:mainfrom
Hidetsugu55:hide/fix/chat-history-empty-fallback
Jun 19, 2026
Merged

fix(gateway): never return an empty chat.history transcript#92383
clawsweeper[bot] merged 2 commits into
openclaw:mainfrom
Hidetsugu55:hide/fix/chat-history-empty-fallback

Conversation

@Hidetsugu55

Copy link
Copy Markdown
Contributor

enforceChatHistoryFinalBudget returned an empty array when even a single oversized-message placeholder could not fit the chat-history byte budget — for example when the source transcript message carried very large metadata (a corrupted or huge __openclaw.id). An empty chat.history response renders as a blank transcript on the dashboard, which reads to the operator as total history loss, even though the full transcript is intact on disk. This is one of the concrete causes behind "the whole chat history disappears".

What changed

  • In the final byte-budget fallback (the branch that previously returned { messages: [] }), return a minimal, metadata-free sentinel message instead. The dashboard now always renders at least a self-describing notice ([chat.history unavailable: transcript too large to display; the full history is preserved on disk]) rather than a blank pane.
  • The sentinel deliberately does not copy the oversized source metadata, so it is guaranteed small and cannot re-trigger the budget overflow.

Tests

  • pnpm exec vitest run --config test/vitest/vitest.gateway.config.ts src/gateway/server-methods/chat-history-budget.test.ts — pass-through, last-message-only, per-message placeholder, and the new sentinel fallback (asserts the result is never empty).
  • Existing src/gateway/server.chat.gateway-server-chat-b.test.ts oversized-history coverage still passes.
  • ./node_modules/.bin/oxfmt --check on the changed files.

Real behavior proof

Behavior or issue addressed: When a session transcript contained a message whose oversized-placeholder representation still exceeded the 6 MB chat-history budget, enforceChatHistoryFinalBudget returned an empty array and the dashboard showed a completely blank transcript — indistinguishable from losing the whole conversation. The fix makes that fallback return a small sentinel notice so the history pane is never blank.

Real environment tested: Ran the actual production chat-history budget pipeline from this branch on macOS (Darwin, Apple Silicon) via node — the same replaceOversizedChatHistoryMessages and enforceChatHistoryFinalBudget functions the gateway's chat.history handler calls — against a pathological transcript message carrying ~7.5 MB of metadata, at the production 6 MB budget.

Exact steps or command run after this patch: node --import tsx proof-empty-history.mts, which builds a real display message with a ~7.5 MB __openclaw.id, runs stage 1 (replaceOversizedChatHistoryMessages) and stage 2 (enforceChatHistoryFinalBudget) exactly as chat.history does, and prints the resulting transcript.

Evidence after fix: Console output from running the production pipeline:

[proofA2] source message bytes: 7500116 (budget 6291456)
[proofA2] after replaceOversized: placeholder bytes=7500177 replacedCount=1
[proofA2] placeholder still exceeds budget? true
[proofA2] enforceChatHistoryFinalBudget -> messages.length=1
[proofA2] first message text: "[chat.history unavailable: transcript too large to display; the full history is preserved on disk]"
[proofA2] carries source metadata? false
[proofA2] PROOF PASS: blank transcript replaced by a self-describing sentinel

Observed result after fix: The pipeline returns a single sentinel message (messages.length=1) carrying the self-describing notice and no oversized metadata. Before this patch the identical input produced messages.length=0 — a blank transcript on the dashboard. The on-disk transcript is untouched either way.

What was not tested: This exercised the production budget functions directly via node rather than through a full websocket chat.history round-trip, because naturally producing a >6 MB single-message placeholder inside a live session is impractical; the surrounding chat.history wiring is covered by the existing gateway server-chat suite. No model or channel was involved.

enforceChatHistoryFinalBudget returned an empty array when even a single
oversized-message placeholder could not fit the chat-history byte budget (for
example when the source message carried very large transcript metadata). An
empty response renders as a blank transcript on the dashboard and reads to the
operator as total history loss, even though the full transcript is intact on
disk.

Return a minimal, metadata-free sentinel message in that fallback instead, so
the dashboard always renders at least a self-describing notice. Adds focused
coverage for the budget tiers including the sentinel path.
@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime size: S proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 12, 2026
@clawsweeper

clawsweeper Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Codex review: passed. Reviewed June 19, 2026, 12:15 AM ET / 04:15 UTC.

Summary
The PR changes gateway chat-history byte-budget fallback behavior to return a small metadata-free unavailable sentinel instead of an empty transcript, with focused budget tests.

PR surface: Source +20, Tests +73. Total +93 across 2 files.

Reproducibility: yes. Source inspection shows current main reaches messages: [] when the full history, last message, and copied oversized placeholder all exceed maxBytes; I did not run tests because this review is read-only.

Review metrics: none identified.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Next step before merge

  • No ClawSweeper repair lane is needed because review found no blocking defect; the automerge opt-in can continue gating the exact head if maintainers keep it enabled.

Security
Cleared: The diff only changes gateway TypeScript and test code and adds no dependency, workflow, secret, package-resolution, or artifact execution surface.

Review details

Best possible solution:

Keep the shared helper-level sentinel and regression coverage so every chat.history consumer receives an explicit unavailable notice instead of an unlabelled blank result for this oversized fallback.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection shows current main reaches messages: [] when the full history, last message, and copied oversized placeholder all exceed maxBytes; I did not run tests because this review is read-only.

Is this the best way to solve the issue?

Yes. The shared final-budget helper is the narrowest maintainable boundary because Gateway WebSocket history, embedded TUI history, and the embedded Gateway stub all call it after the same replacement and byte-cap stages.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 78f948f76836.

Label changes

Label changes:

  • add status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (terminal): The PR body includes after-fix terminal output from the production chat-history budget functions showing one metadata-free sentinel instead of an empty history.
  • remove status: 👀 ready for maintainer look: Current PR status label is status: 🚀 automerge armed.

Label justifications:

  • P2: The PR addresses a limited gateway/WebChat history-display bug where a pathological oversized transcript projection can become a blank history response.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (terminal): The PR body includes after-fix terminal output from the production chat-history budget functions showing one metadata-free sentinel instead of an empty history.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output from the production chat-history budget functions showing one metadata-free sentinel instead of an empty history.
Evidence reviewed

PR surface:

Source +20, Tests +73. Total +93 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 21 1 +20
Tests 1 73 0 +73
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 94 1 +93

What I checked:

Likely related people:

  • vincentkoc: Current blame for the chat-history budget helper and embedded sibling call sites points to recent gateway release-unblock work on these paths. (role: recent area contributor; confidence: high; commits: 74f90885f351; files: src/gateway/server-methods/chat.ts, src/tui/embedded-backend.ts, src/agents/tools/embedded-gateway-stub.ts)
  • rickqdev: PR history maps the original chat.history oversized-payload hard cap to this author’s merged PR, which created the bounded placeholder path this PR refines. (role: introduced hard-cap behavior; confidence: high; commits: 5d9a026a9e8b; files: src/gateway/server-methods/chat.ts)
  • sebslight: Recent history includes a focused chat.history hard-cap context-preservation change by this author in the same helper area. (role: adjacent hard-cap contributor; confidence: medium; commits: 81fd771cb998; files: src/gateway/server-methods/chat.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 12, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 12, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 12, 2026
@vincentkoc

Copy link
Copy Markdown
Member

/clownfish automerge

@vincentkoc vincentkoc added clownfish:automerge Maintainer opted this Clownfish PR into bounded ClawSweeper-reviewed automerge clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge labels Jun 19, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Clownfish is on the reef for this PR. 🐠

I tagged clownfish:automerge and sent ClawSweeper over this exact head. If the sweep finds rough coral, failing checks, or needs-human, I will take another bounded repair lap and ask for a fresh review.

A maintainer can call /clownfish stop any time and I will drift this back to human review.

@clawsweeper clawsweeper Bot removed the status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. label Jun 19, 2026
@clawsweeper clawsweeper Bot added the status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane. label Jun 19, 2026
@clawsweeper clawsweeper Bot merged commit 50a4bb0 into openclaw:main Jun 19, 2026
240 of 258 checks passed
@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

🦞✅
ClawSweeper merged this PR after the passing review.

Source: clawsweeper[bot]
Feedback: structured ClawSweeper verdict: pass (sha=f2fa246ab79ca1d2095b32d001792d23b28e4516)
Merge status: merged by ClawSweeper automerge
Merged at: 2026-06-19T04:17:03Z
Merge commit: 50a4bb00e557

What merged:

  • The PR changes gateway chat-history byte-budget fallback behavior to return a small metadata-free unavailable sentinel instead of an empty transcript, with focused budget tests.
  • PR surface: Source +20, Tests +73. Total +93 across 2 files.
  • Reproducibility: yes. Source inspection shows current main reaches messages: [] when the full history, las ... d copied oversized placeholder all exceed maxBytes; I did not run tests because this review is read-only.

Automerge notes:

  • PR branch already contained follow-up commit before automerge: test: access __openclaw via bracket notation for no-underscore-dangle

The automerge loop is complete.

Automerge progress:

  • 2026-06-19 04:16:40 UTC review passed f2fa246ab79c (structured ClawSweeper verdict: pass (sha=f2fa246ab79ca1d2095b32d001792d23b28e4...)
  • 2026-06-19 04:17:06 UTC merged f2fa246ab79c (merged by ClawSweeper automerge)

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 19, 2026
…#92383)

Summary:
- The PR changes gateway chat-history byte-budget fallback behavior to return a small metadata-free unavailable sentinel instead of an empty transcript, with focused budget tests.
- PR surface: Source +20, Tests +73. Total +93 across 2 files.
- Reproducibility: yes. Source inspection shows current main reaches `messages: []` when the full history, las ... d copied oversized placeholder all exceed `maxBytes`; I did not run tests because this review is read-only.

Automerge notes:
- PR branch already contained follow-up commit before automerge: test: access __openclaw via bracket notation for no-underscore-dangle

Validation:
- ClawSweeper review passed for head f2fa246.
- Required merge gates passed before the squash merge.

Prepared head SHA: f2fa246
Review: openclaw#92383 (comment)

Co-authored-by: Hidetsugu55 <183473679+Hidetsugu55@users.noreply.github.com>
cxbAsDev pushed a commit to cxbAsDev/openclaw that referenced this pull request Jun 23, 2026
…#92383)

Summary:
- The PR changes gateway chat-history byte-budget fallback behavior to return a small metadata-free unavailable sentinel instead of an empty transcript, with focused budget tests.
- PR surface: Source +20, Tests +73. Total +93 across 2 files.
- Reproducibility: yes. Source inspection shows current main reaches `messages: []` when the full history, las ... d copied oversized placeholder all exceed `maxBytes`; I did not run tests because this review is read-only.

Automerge notes:
- PR branch already contained follow-up commit before automerge: test: access __openclaw via bracket notation for no-underscore-dangle

Validation:
- ClawSweeper review passed for head f2fa246.
- Required merge gates passed before the squash merge.

Prepared head SHA: f2fa246
Review: openclaw#92383 (comment)

Co-authored-by: Hidetsugu55 <183473679+Hidetsugu55@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge clownfish:automerge Maintainer opted this Clownfish PR into bounded ClawSweeper-reviewed automerge gateway Gateway runtime P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants