Skip to content

fix(gateway): stop stale control ui auth retry loops#81771

Merged
BunsDev merged 1 commit into
mainfrom
meow/control-ui-auth-history-72139
May 14, 2026
Merged

fix(gateway): stop stale control ui auth retry loops#81771
BunsDev merged 1 commit into
mainfrom
meow/control-ui-auth-history-72139

Conversation

@BunsDev

@BunsDev BunsDev commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Behavior addressed

A stale Control UI token no longer keeps reconnecting every backoff interval when there is no cached device-token fallback to try. Slow/large chat history rendering is also capped by raw tool-output payload size so a dashboard tab is less able to starve channel sockets.

Real environment tested

Local Codex worktree on macOS, Node v24.13.0, pnpm v10.33.2, focused Vitest through the repo node scripts/run-vitest.mjs wrapper.

Exact steps or command run after this patch

node scripts/run-vitest.mjs ui/src/ui/gateway.node.test.ts src/gateway/client.test.ts ui/src/ui/chat/build-chat-items.test.ts
node scripts/run-vitest.mjs src/gateway/reconnect-gating.test.ts ui/src/ui/controllers/chat.test.ts ui/src/ui/views/chat.test.ts
pnpm exec oxfmt --check --threads=1 CHANGELOG.md ui/src/ui/gateway.ts ui/src/ui/gateway.node.test.ts ui/src/ui/chat/history-limits.ts ui/src/ui/chat/build-chat-items.ts ui/src/ui/chat/build-chat-items.test.ts src/gateway/client.ts src/gateway/client.test.ts
git diff --check

Evidence after fix

  • Focused gateway/chat history regression run: 4 files passed, 127 tests passed.
  • Adjacent reconnect/chat controller/view run: 4 files passed, 115 tests passed.
  • Formatter check: all matched files use the correct format.
  • Whitespace check: clean.
  • Commit signature verified locally with git log -1 --show-signature.

Observed result after fix

  • Browser Control UI client pauses after AUTH_TOKEN_MISMATCH when local storage has no trusted device token to retry, instead of creating another WebSocket.
  • Node Gateway client pauses reconnect and calls onReconnectPaused for the same no-fallback token mismatch case.
  • The trusted cached-device-token retry path remains intact.
  • Chat history windowing now includes raw tool-result content in the render-size budget and tolerates malformed history entries.

What was not tested

  • pnpm check:changed through Testbox was not completed. node scripts/crabbox-wrapper.mjs run --provider blacksmith-testbox --timing-json --shell -- "pnpm check:changed" failed because .github/workflows/crabbox-hydrate.yml does not contain a Blacksmith testbox step, then the wrapper hung and was stopped.
  • No live browser stale-token smoke was run.
  • No live Slack Socket Mode pong-timeout reproduction was run; the source-level auth loop and history-budget behavior are covered by focused tests.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime size: M maintainer Maintainer-authored PR labels May 14, 2026
@BunsDev
BunsDev force-pushed the meow/control-ui-auth-history-72139 branch from 30a276d to 934f67c Compare May 14, 2026 09:32
@clawsweeper

clawsweeper Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

Summary
The PR changes browser and Node gateway reconnect gating for AUTH_TOKEN_MISMATCH, adds bounded Control UI chat-history character-budget windowing with regression tests, and updates the changelog.

Reproducibility: yes. for source-level reproduction: current browser and Node clients can keep reconnecting on AUTH_TOKEN_MISMATCH when no stored device-token retry exists, and current chat history rendering is count-capped only. I did not reproduce the live Slack Socket Mode disconnect in this read-only pass.

Real behavior proof
Not applicable: The external-contributor proof gate does not apply to this member/maintainer-labeled PR; the body reports focused test and formatter runs but no live browser or Slack smoke.

Next step before merge
Manual maintainer review/landing is the right next action because this is a protected maintainer/member PR with no discrete automated repair finding and remaining validation choices around live/browser and broad gates.

Security
Cleared: The diff touches auth retry and UI history traversal but adds no dependency, workflow, secret, or package-resolution changes; the bounded estimator avoids the prior client-side DoS concern.

Review details

Best possible solution:

Land this or an equivalent maintainer-reviewed patch that preserves one-shot trusted device-token recovery, stops stale token-mismatch reconnect loops without a queued fallback, keeps the current 100-message cap, and closes #72139 after validation.

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

Yes for source-level reproduction: current browser and Node clients can keep reconnecting on AUTH_TOKEN_MISMATCH when no stored device-token retry exists, and current chat history rendering is count-capped only. I did not reproduce the live Slack Socket Mode disconnect in this read-only pass.

Is this the best way to solve the issue?

Yes, the PR direction is the narrow maintainable fix: gate reconnects on an actually queued trusted fallback and add UI-local bounded render budgeting. The safer landing path is maintainer validation rather than automated cleanup or a separate repair PR.

What I checked:

  • protected/member PR state: GitHub context shows author association MEMBER and the protected maintainer label, so this workflow must keep the PR open for explicit maintainer handling. (934f67c2e665)
  • current browser reconnect gap: Current main only queues device-token retry when a stored token, trusted endpoint, explicit shared token, and retry hint are all present; the close handler otherwise still falls through to scheduleReconnect() for an initial AUTH_TOKEN_MISMATCH. (ui/src/ui/gateway.ts:402, 365c986a5b2a)
  • current Node reconnect gap: Current main's Node client pauses token mismatch reconnects only when the endpoint is untrusted or the retry budget has already been consumed, so a trusted endpoint with no queued stored-token retry can keep reconnecting. (src/gateway/client.ts:698, 365c986a5b2a)
  • protocol contract: Gateway protocol docs define AUTH_TOKEN_MISMATCH recovery as one bounded trusted cached-device-token retry, then clients should stop automatic reconnect loops and surface operator action guidance. Public docs: docs/gateway/protocol.md. (docs/gateway/protocol.md:723, 365c986a5b2a)
  • current chat history gap: Current main still windows chat history by the 100-message count cap only in buildChatItems, with no UI render-character budget in history-limits.ts. (ui/src/ui/chat/build-chat-items.ts:317, 365c986a5b2a)
  • PR diff addresses prior chat-budget review issues: The downloaded PR diff preserves CHAT_HISTORY_RENDER_LIMIT = 100, adds CHAT_HISTORY_RENDER_CHAR_BUDGET, counts raw content/text/args fields with WeakSet/depth/node/budget bounds, and adds tests for raw tool_result.content and malformed entries. (ui/src/ui/chat/build-chat-items.ts:327, 934f67c2e665)

Likely related people:

  • BunsDev: Prior merged history under Val Alexander touches Control UI auth failure handling and recent Control UI refresh/chat-history behavior, and this member PR is in the same surface. (role: recent area contributor; confidence: high; commits: 79ae8148f79c, 5ae385b2f0f1, 4935e24c7a7f; files: ui/src/ui/gateway.ts, ui/src/ui/chat/build-chat-items.ts, ui/src/ui/chat/history-limits.ts)
  • joshavant: Commit history shows work hardening cached-token fallback, reconnect gating, protocol docs, and tests in the affected gateway/client paths. (role: auth reconnect behavior contributor; confidence: high; commits: a76e81019333; files: ui/src/ui/gateway.ts, src/gateway/client.ts, ui/src/ui/gateway.node.test.ts)
  • vincentkoc: Recent current-main history and the related chat-budget PR context show WebChat reload/reconciliation work adjacent to the history-rendering surface. (role: recent adjacent WebChat contributor; confidence: medium; commits: cff991c88d04, 02908db62b30; files: ui/src/ui/chat/build-chat-items.ts, ui/src/ui/controllers/chat.ts)
  • steipete: Current-main blame for the affected files and commit history show recent integration/release work plus the chat item builder extraction in the same UI path. (role: recent area contributor and integrator; confidence: medium; commits: bfc798bd0b2a, 68954f9c6ccb; files: ui/src/ui/gateway.ts, src/gateway/client.ts, ui/src/ui/chat/build-chat-items.ts)

Remaining risk / open question:

  • This read-only pass did not run the PR's focused tests; correctness is based on source, diff, docs, and discussion review plus the PR body's reported commands.
  • No live browser stale-token smoke or live Slack Socket Mode pong-timeout reproduction was inspected; the source-level auth loop and UI render-budget paths are the high-confidence proof.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 365c986a5b2a.

@BunsDev
BunsDev force-pushed the meow/control-ui-auth-history-72139 branch from 934f67c to d969255 Compare May 14, 2026 10:31
@BunsDev

BunsDev commented May 14, 2026

Copy link
Copy Markdown
Contributor Author

Pre-merge verification for head d9692555ee:

Local focused proof after rebasing on latest origin/main:

node scripts/run-vitest.mjs ui/src/ui/gateway.node.test.ts src/gateway/client.test.ts ui/src/ui/chat/build-chat-items.test.ts
# 4 files passed, 127 tests passed

node scripts/run-vitest.mjs src/gateway/reconnect-gating.test.ts ui/src/ui/controllers/chat.test.ts ui/src/ui/views/chat.test.ts
# 4 files passed, 115 tests passed

pnpm exec oxfmt --check --threads=1 CHANGELOG.md ui/src/ui/gateway.ts ui/src/ui/gateway.node.test.ts ui/src/ui/chat/history-limits.ts ui/src/ui/chat/build-chat-items.ts ui/src/ui/chat/build-chat-items.test.ts src/gateway/client.ts src/gateway/client.test.ts
# all matched files use the correct format

git diff --check
# clean

GitHub proof on d9692555ee:

  • Real behavior proof: run 25855231600 passed.
  • CI/check graph: run 25855232828 passed, including check, check-additional, build-artifacts, build-smoke, gateway/core/UI shards, lint, types, policy/preflight guards, and node checks selected for this diff.
  • Security High: run 25855232863 passed.
  • Critical Quality shard selection and network-runtime-boundary: run 25855232865 passed or skipped non-selected shards.
  • Path scan: run 25855232831 passed.
  • actionlint/no-tabs/generated-doc-baseline workflow: run 25855232848 passed or skipped non-applicable docs baseline.

Known proof gaps:

  • No live Slack Socket Mode pong-timeout reproduction was run.
  • No manual browser stale-token smoke was run; the browser and Node reconnect behavior is covered by focused regression tests.
  • The earlier local Testbox pnpm check:changed wrapper path was blocked because .github/workflows/crabbox-hydrate.yml lacks a Blacksmith testbox step, but the PR CI check graph for this head passed.

@BunsDev
BunsDev merged commit 348ffe6 into main May 14, 2026
112 checks passed
@BunsDev
BunsDev deleted the meow/control-ui-auth-history-72139 branch May 14, 2026 10:36
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 gateway Gateway runtime maintainer Maintainer-authored PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Control UI auth retry loop + blocking chat.history causes Slack Socket Mode disconnects

1 participant