Skip to content

fix: stop reconnecting on protocol mismatch#98414

Merged
steipete merged 6 commits into
openclaw:mainfrom
haruaiclone-droid:codex/fix-protocol-mismatch-terminal
Jul 6, 2026
Merged

fix: stop reconnecting on protocol mismatch#98414
steipete merged 6 commits into
openclaw:mainfrom
haruaiclone-droid:codex/fix-protocol-mismatch-terminal

Conversation

@haruaiclone-droid

@haruaiclone-droid haruaiclone-droid commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Closes #98413.

What Problem This Solves

When the Control UI and Gateway disagree on the connection protocol, the Gateway returns PROTOCOL_MISMATCH. The browser surfaced the failure but treated it like a retryable disconnect, opening another WebSocket every retry interval and repeating a connection that cannot succeed.

Why This Change Was Made

The fix keeps normalized protocol-mismatch details on GatewayRequestError and classifies that structured error as a non-recoverable connect failure. This extends the existing authentication/pairing reconnect gate instead of adding a second retry policy. Ordinary transient closes and explicitly retryable pairing flows keep their existing reconnect behavior.

User Impact

Users now get the existing actionable protocol guidance once, without a reconnect loop. Updating the mismatched client or Gateway remains the supported recovery path.

Evidence

  • Added focused reconnect-gating coverage for protocol mismatch plus the existing authentication, pairing, and transient-close cases.
  • Added Control UI Gateway unit coverage that preserves normalized mismatch details and suppresses reconnect.
  • Added a real-Chromium Control UI E2E that injects PROTOCOL_MISMATCH, verifies the rendered guidance, waits beyond the retry window, and asserts that only one Gateway connect request was sent.
  • Exact-head sanitized AWS Crabbox run run_04a548fbf6ec passed pnpm tsgo:test:src, all 42 reconnect-gating assertions, all 38 Gateway unit assertions, and all 4 login-gate.e2e.test.ts real-Chromium scenarios on 87f41b7c1a06fb8bf6cef8428a2baea8c82b0956.
  • The browser proof renders the protocol guidance, waits beyond the initial retry backoff, and confirms only one Gateway connect request; unrelated Vite HMR sockets are deliberately excluded from that assertion.
  • Fresh autoreview found no accepted/actionable defects.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui size: XS triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 1, 2026
@clawsweeper

clawsweeper Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed July 6, 2026, 2:01 AM ET / 06:01 UTC.

Summary
The PR updates the Control UI Gateway client to treat protocol-mismatch connect failures as non-recoverable, preserves normalized mismatch details, adds focused reconnect/unit/E2E coverage, and currently adds one changelog entry.

PR surface: Source -2, Tests +66, Docs +1. Total +65 across 5 files.

Reproducibility: yes. Source inspection shows current main can schedule reconnects after a PROTOCOL_MISMATCH connect failure because stored details and the non-recoverable gate do not classify that terminal detail code; I did not execute tests in this read-only review.

Review metrics: 1 noteworthy metric.

  • Release-owned changelog entries: 1 added. CHANGELOG.md is release-owned, so normal PR release-note context should stay in the PR body instead of changing the generated release file.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #98413
Summary: This PR is the focused Control UI fix candidate for the linked browser reconnect-loop bug; macOS/mobile protocol-mismatch items overlap by detail-code semantics but own separate client surfaces.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
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:

  • Remove the added CHANGELOG.md line and keep the release-note text in the PR body.

Risk before merge

  • [P1] The direct changelog line keeps release-note bookkeeping in a release-owned file; remove it before merge so release generation remains the source of truth.

Maintainer options:

  1. Decide the mitigation before merge
    Land the Control UI runtime and test changes after dropping the direct CHANGELOG.md edit and keeping the release-note context in the PR body.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] A mechanical repair can remove the direct changelog entry without touching the tested runtime fix.

Security
Cleared: The diff changes Control UI reconnect classification and tests without dependency, workflow, secret, permission, or package-resolution changes.

Review findings

  • [P3] Remove the release-owned changelog entry — CHANGELOG.md:27
Review details

Best possible solution:

Land the Control UI runtime and test changes after dropping the direct CHANGELOG.md edit and keeping the release-note context in the PR body.

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

Yes. Source inspection shows current main can schedule reconnects after a PROTOCOL_MISMATCH connect failure because stored details and the non-recoverable gate do not classify that terminal detail code; I did not execute tests in this read-only review.

Is this the best way to solve the issue?

Yes for the Control UI runtime path: normalizing details once in GatewayRequestError and feeding the existing reconnect gate is the narrow maintainable fix. The direct CHANGELOG.md edit is not part of the best solution and should be removed.

Full review comments:

  • [P3] Remove the release-owned changelog entry — CHANGELOG.md:27
    This was already raised in the previous ClawSweeper cycle and is still present. Root AGENTS.md says CHANGELOG.md is release-owned for normal PRs; the PR body already carries the release-note context, so this line should be dropped before merge.
    Confidence: 0.95

Overall correctness: patch is correct
Overall confidence: 0.9

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body and maintainer comment report exact-head sanitized AWS Crabbox real-Chromium proof that rendered protocol guidance and observed one Gateway connect request after waiting past the retry window.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body and maintainer comment report exact-head sanitized AWS Crabbox real-Chromium proof that rendered protocol guidance and observed one Gateway connect request after waiting past the retry window.

Label justifications:

  • P2: This is a normal-priority Control UI Gateway reconnect-loop fix with limited blast radius to protocol-mismatch connection failures.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body and maintainer comment report exact-head sanitized AWS Crabbox real-Chromium proof that rendered protocol guidance and observed one Gateway connect request after waiting past the retry window.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body and maintainer comment report exact-head sanitized AWS Crabbox real-Chromium proof that rendered protocol guidance and observed one Gateway connect request after waiting past the retry window.
Evidence reviewed

PR surface:

Source -2, Tests +66, Docs +1. Total +65 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 1 8 10 -2
Tests 3 89 23 +66
Docs 1 1 0 +1
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 5 98 33 +65

Acceptance criteria:

  • [P1] git diff --check.
  • [P1] Confirm the PR diff no longer includes CHANGELOG.md.

What I checked:

  • Current main stores display-only protocol details: Current main formats bare protocol-mismatch errors with enriched details, but stores the original details on GatewayRequestError, so later reconnect policy cannot read normalized PROTOCOL_MISMATCH details. (ui/src/api/gateway.ts:69, f9bf5f589763)
  • Current main reconnect gate omits protocol mismatch: Current main's non-recoverable reconnect gate lists terminal auth/pairing codes but not PROTOCOL_MISMATCH, while the close handler schedules reconnect when that gate returns false. (ui/src/api/gateway.ts:121, f9bf5f589763)
  • Gateway contract emits structured mismatch details: The Gateway protocol-negotiation path sends details.code PROTOCOL_MISMATCH before closing an incompatible client, so the UI has a structured detail code to classify. (src/gateway/server/ws-connection/message-handler.ts:826, f9bf5f589763)
  • PR head fixes the Control UI classification path: The PR head stores enriched details on GatewayRequestError, renames the gate to isNonRecoverableConnectError, and includes PROTOCOL_MISMATCH in the terminal detail-code list used by the close handler. (ui/src/api/gateway.ts:69, 87f41b7c1a06)
  • PR head covers browser behavior: The E2E test injects a PROTOCOL_MISMATCH connect rejection, checks the rendered protocol guidance, waits past the retry window, and asserts a single connect request. (ui/src/e2e/login-gate.e2e.test.ts:83, 87f41b7c1a06)
  • Release-owned changelog policy applies: Root AGENTS.md says CHANGELOG.md is release-only, normal PRs should not edit it, and release generation owns the file. (AGENTS.md:238, f9bf5f589763)

Likely related people:

  • steipete: Current-main blame points to recent Peter Steinberger work around the Control UI reconnect gate, and the live PR timeline shows steipete assigned and force-pushed the current head revisions. (role: recent area contributor and current PR assignee; confidence: high; commits: f53103de72da, 9c410a4b75db, 87f41b7c1a06; files: ui/src/api/gateway.ts, src/gateway/reconnect-gating.test.ts, ui/src/e2e/login-gate.e2e.test.ts)
  • ruanrrn: Merged PR fix(ui): propagate connect errors to pending requests #54758 preserved structured Control UI connect failures in the same Gateway API module that this PR extends. (role: recent adjacent contributor; confidence: medium; commits: e9a5dc9bf672; files: ui/src/api/gateway.ts, ui/src/api/gateway.node.test.ts)
  • BunsDev: Merged PR fix(gateway): stop stale control ui auth retry loops #81771 addressed stale Control UI auth retry loops, which is adjacent to this PR's reconnect gating behavior. (role: adjacent prior fix owner; confidence: medium; commits: 348ffe60612c; files: ui/src/api/gateway.ts, src/gateway/reconnect-gating.test.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.
Review history (3 earlier review cycles)
  • reviewed 2026-07-01T04:57:07.821Z sha b5fb210 :: needs real behavior proof before merge. :: [P2] Apply the protocol-mismatch pause to the shared client too
  • reviewed 2026-07-06T05:39:36.736Z sha 8e74e56 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-06T05:54:28.591Z sha 87f41b7 :: needs changes before merge. :: [P3] Remove the release-owned changelog entry

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jul 1, 2026
@steipete steipete self-assigned this Jul 6, 2026
@steipete
steipete force-pushed the codex/fix-protocol-mismatch-terminal branch from b5fb210 to cd9f687 Compare July 6, 2026 05:10
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S and removed size: XS labels Jul 6, 2026
@steipete
steipete force-pushed the codex/fix-protocol-mismatch-terminal branch from cd9f687 to bd769b4 Compare July 6, 2026 05:21
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 6, 2026
@steipete
steipete force-pushed the codex/fix-protocol-mismatch-terminal branch from bd769b4 to 8e74e56 Compare July 6, 2026 05:31
@clawsweeper clawsweeper Bot removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 6, 2026
@steipete
steipete marked this pull request as ready for review July 6, 2026 05:37
@steipete
steipete force-pushed the codex/fix-protocol-mismatch-terminal branch from 8e74e56 to bc7cefe Compare July 6, 2026 05:42
@steipete
steipete force-pushed the codex/fix-protocol-mismatch-terminal branch from bc7cefe to 87f41b7 Compare July 6, 2026 05:47
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Maintainer refactor and exact-head verification are complete.

  • Reused the existing Gateway reconnect-policy owner; structured PROTOCOL_MISMATCH details now survive normalization and stop reconnecting.
  • Preserved ordinary transient reconnects plus the existing pairing and bounded device-token retry paths.
  • Sanitized AWS Crabbox run_04a548fbf6ec on immutable head 87f41b7c1a06fb8bf6cef8428a2baea8c82b0956 passed pnpm tsgo:test:src, 42 reconnect-policy assertions, 38 Control UI Gateway assertions, and 4 real-Chromium login-gate scenarios.
  • The browser scenario renders the supported-protocol guidance, waits beyond the initial backoff, and proves no second Gateway connect request is sent.
  • Fresh autoreview: no accepted/actionable findings. Known proof gaps: none for the changed reconnect behavior.

Ready to land through the repository-native prepare/merge guard.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jul 6, 2026
@clawsweeper clawsweeper Bot added the status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. label Jul 6, 2026
@steipete
steipete merged commit ead92d7 into openclaw:main Jul 6, 2026
125 of 129 checks passed
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

vincentkoc added a commit to zhangqueping/openclaw that referenced this pull request Jul 6, 2026
* origin/main: (1287 commits)
  fix(android): block loopback canvas navigation (openclaw#99874)
  fix(hooks): suppress unhandled stdout/stderr stream errors in gmail watcher (openclaw#100519)
  fix(memory-core): guard qmd mcporter JSON.parse against non-JSON stdout (openclaw#98381)
  fix(build): fall back to tsx for build TypeScript scripts (openclaw#91262)
  feat(skills): suggest saving detected reusable workflows by default (openclaw#95477) (openclaw#100692)
  docs(changelog): remove generated release-note entries
  feat(telegram): offer BotFather web app flow in setup help and docs (openclaw#100540)
  fix(ios): unify Talk and Settings row typography on one branded detail row (openclaw#100515)
  feat(gateway): add persisted crash-loop breaker and fatal-config exit contract
  refactor(macos): lock and unify PortGuardian tunnel record persistence so concurrent app instances cannot lose orphan records (openclaw#100601)
  fix: stop reconnecting on protocol mismatch (openclaw#98414)
  fix(maint): reuse recent hosted gates after rebase (openclaw#100663)
  fix(ui): reopen web terminals without stale content (openclaw#100665)
  fix(browser): diagnose empty WSL2 Chrome replies (openclaw#100590)
  fix(ios): chat snaps back to bottom when scrolling to top via status-bar tap (openclaw#100502)
  Treat already-compacted CLI compaction as no-op (openclaw#99136)
  docs(changelog): remove direct main fix entry
  fix(feishu): strip internal tool-trace banners from outbound text (openclaw#98705)
  fix(message): thread --limit through to CLI formatter and surface provider pagination hints (openclaw#99089)
  fix(voyage): close response body stream when batch output JSONL parsing throws (openclaw#98840)
  ...

# Conflicts:
#	extensions/memory-wiki/package.json
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 6, 2026
* fix: stop reconnecting on protocol mismatch

* fix(ui): stop protocol mismatch reconnects

* test(ui): assert protocol mismatch recovery copy

* test(ui): count gateway reconnect attempts

* test(gateway): keep detail-less reconnect case typed

* test(gateway): keep pairing retry fixture typed

---------

Co-authored-by: haruaiclone-droid <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
* fix: stop reconnecting on protocol mismatch

* fix(ui): stop protocol mismatch reconnects

* test(ui): assert protocol mismatch recovery copy

* test(ui): count gateway reconnect attempts

* test(gateway): keep detail-less reconnect case typed

* test(gateway): keep pairing retry fixture typed

---------

Co-authored-by: haruaiclone-droid <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
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 P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Control UI reconnects after protocol mismatch connect failures

2 participants