Skip to content

fix(ui): track gateway protocol constants#82883

Merged
galiniliev merged 2 commits into
openclaw:mainfrom
galiniliev:bug-018-control-ui-protocol-version
May 17, 2026
Merged

fix(ui): track gateway protocol constants#82883
galiniliev merged 2 commits into
openclaw:mainfrom
galiniliev:bug-018-control-ui-protocol-version

Conversation

@galiniliev

@galiniliev galiniliev commented May 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: the browser Control UI still advertised Gateway protocol range 4..4 after the Gateway protocol constants moved to 5.
  • Why it matters: the Gateway rejects the browser connect frame with code=1002 reason=protocol mismatch, leaving the operator UI unable to connect.
  • What changed: ui/src/ui/gateway.ts now uses MIN_CLIENT_PROTOCOL_VERSION and PROTOCOL_VERSION from the shared Gateway protocol constants, and the node UI gateway test asserts those emitted fields.
  • What did NOT change (scope boundary): no Gateway server compatibility behavior, stale-service-worker handling, or native client protocol handling changed.

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

Real behavior proof (required for external PRs)

  • Behavior addressed: Browser Control UI connect frames now advertise the shared current Gateway protocol range instead of stale literal protocol 4 values.
  • Real environment tested: Windows source checkout at commit 31ca8b2a670fcc41513f75cc52f4c506908a59b8; local shell with Node v24.15.0. The reported failing environment was a browser Control UI served by pnpm ui:dev against a local Gateway on loopback port 18789.
  • Exact steps or command run after this patch: Inspected current source for remaining protocol literals, ran patch hygiene, and ran a source-level terminal assertion that the browser connect builder uses MIN_CLIENT_PROTOCOL_VERSION / PROTOCOL_VERSION and that the regression test asserts both emitted fields.
  • Evidence after fix:
$ git diff --check
exit code 0, no whitespace errors

$ node -e "const fs=require('fs'); const src=fs.readFileSync('ui/src/ui/gateway.ts','utf8'); const test=fs.readFileSync('ui/src/ui/gateway.node.test.ts','utf8'); const checks=[/MIN_CLIENT_PROTOCOL_VERSION/,/PROTOCOL_VERSION/,/minProtocol: MIN_CLIENT_PROTOCOL_VERSION/,/maxProtocol: PROTOCOL_VERSION/]; for (const re of checks) if (!re.test(src)) throw new Error('missing '+re); if (/minProtocol: 4|maxProtocol: 4/.test(src)) throw new Error('hardcoded protocol remains'); if (!/connectFrame\\.params\\?\\.minProtocol\\)\\.toBe\\(MIN_CLIENT_PROTOCOL_VERSION\\)/.test(test)) throw new Error('missing minProtocol assertion'); if (!/connectFrame\\.params\\?\\.maxProtocol\\)\\.toBe\\(PROTOCOL_VERSION\\)/.test(test)) throw new Error('missing maxProtocol assertion'); console.log('source assertions passed: UI connect params use shared protocol constants and test asserts them');"
source assertions passed: UI connect params use shared protocol constants and test asserts them
  • Observed result after fix: ui/src/ui/gateway.ts has no remaining minProtocol: 4 or maxProtocol: 4 literals; the emitted connect params are wired to the shared protocol constants that currently evaluate to 5.
  • What was not tested: Focused Vitest and ui:build could not be completed in this local Windows checkout because dependency install and command shims are blocked by local process-spawn permission failures. pnpm install retried once and failed in esbuild postinstall with spawnSync ... EPERM; node scripts/run-vitest.mjs ui/src/ui/gateway.node.test.ts failed with spawn EPERM; direct Vitest and Bun Vitest attempts timed out without useful output; Crabbox was unavailable because the local wrapper failed binary sanity checks; WSL had no Node installed.
  • Before evidence:
Redacted Gateway log excerpt from the failing browser Control UI handshake:
protocol mismatch remote=127.0.0.1 client=openclaw-control-ui webchat vcontrol-ui
closed before connect remote=127.0.0.1 origin=http://localhost:5173 host=localhost:18789 code=1002 reason=protocol mismatch

Structured fields:
cause=protocol-mismatch
lastFrameMethod=connect
minProtocol=4
maxProtocol=4
expectedProtocol=5
minimumProbeProtocol=5
client=openclaw-control-ui
mode=webchat
version=control-ui
platform=Win32

Root Cause (if applicable)

  • Root cause: ui/src/ui/gateway.ts encoded protocol 4 as a literal in both the GatewayConnectParams type and buildConnectParams, so Gateway protocol bumps did not update the browser Control UI client.
  • Missing detection / guardrail: the existing browser gateway tests did not assert the emitted minProtocol and maxProtocol fields against the shared protocol constants.
  • Contributing context (if known): native protocol levels already have guard coverage, but the browser Control UI client did not share that guardrail.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: ui/src/ui/gateway.node.test.ts
  • Scenario the test should lock in: a browser Control UI connect frame advertises MIN_CLIENT_PROTOCOL_VERSION as minProtocol and PROTOCOL_VERSION as maxProtocol.
  • Why this is the smallest reliable guardrail: the failure is in the connect frame builder before the Gateway accepts or rejects the WebSocket handshake.
  • Existing test that already covers this (if any): none for the browser connect protocol fields.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

The browser Control UI can connect to a protocol 5 Gateway after the protocol bump instead of repeatedly failing the handshake with protocol mismatch.

Diagram (if applicable)

Before:
Control UI connect frame -> minProtocol=4/maxProtocol=4 -> Gateway protocol 5 rejection

After:
Control UI connect frame -> shared protocol constants -> Gateway protocol 5 handshake can proceed

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: Windows browser client against local Gateway logs; patch built in a Windows source checkout.
  • Runtime/container: Node v24.15.0 locally; no container proof.
  • Model/provider: NOT_ENOUGH_INFO
  • Integration/channel (if any): Browser Control UI / Gateway WebSocket
  • Relevant config (redacted): local Gateway loopback port 18789; Vite Control UI origin http://localhost:5173

Steps

  1. Run current Gateway with PROTOCOL_VERSION = 5.
  2. Serve the browser Control UI with pnpm ui:dev.
  3. Open the UI and let it connect to ws://127.0.0.1:18789.

Expected

  • The Control UI advertises the current shared protocol range and the Gateway accepts the version range.

Actual

  • Before this patch, the Control UI advertised minProtocol=4 and maxProtocol=4; the Gateway logged expectedProtocol=5 and closed with code=1002 reason=protocol mismatch.

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: confirmed current origin/main still hardcoded protocol 4 in the browser Control UI; confirmed the patch removes the stale literals and wires the connect builder/test to the shared protocol constants; ran git diff --check and source-level terminal assertions.
  • Edge cases checked: searched for remaining minProtocol: 4 / maxProtocol: 4 literals under ui/src and src/gateway/protocol.
  • What you did not verify: focused Vitest, UI build, and live browser reconnection after patch were blocked by local Windows spawn/toolchain failures described above.

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

  • Risk: local automated test execution was blocked in this checkout.
    • Mitigation: the change is narrow, a regression assertion was added, and the exact local blocker is documented so CI or a clean maintainer environment can run the intended Vitest/build proof.

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui size: XS maintainer Maintainer-authored PR labels May 17, 2026
@clawsweeper

clawsweeper Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge.

Summary
The PR updates the browser Control UI Gateway connect params to use shared protocol constants, adds node UI gateway assertions for those fields, and adds a changelog entry.

Reproducibility: yes. from source inspection: current main emits browser protocol 4..4, shared Gateway constants are 5, and the server rejects ranges that exclude 5. I did not run the live browser flow in this read-only review.

Real behavior proof
Needs stronger real behavior proof before merge: The PR provides before logs and after source-level terminal assertions, but it does not show an after-fix browser Control UI to Gateway runtime handshake; the contributor should add redacted logs, terminal output, recording, or equivalent runtime proof before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, ask a maintainer to comment @clawsweeper re-review.

Next step before merge
The PR is protected by the maintainer label and needs contributor-supplied after-fix runtime proof; there is no narrow ClawSweeper repair to make from this review.

Security
Cleared: The diff only changes local UI protocol constants, a focused test assertion, and changelog text, with no new dependency, workflow, permission, secret, or code-execution surface.

Review details

Best possible solution:

Land the narrow constants/test/changelog fix after maintainer review and redacted after-fix runtime or Testbox proof shows the browser Control UI connects to a protocol 5 Gateway.

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

Yes, from source inspection: current main emits browser protocol 4..4, shared Gateway constants are 5, and the server rejects ranges that exclude 5. I did not run the live browser flow in this read-only review.

Is this the best way to solve the issue?

Yes. Reusing the shared Gateway protocol constants in the browser client and asserting the emitted fields is the narrowest maintainable fix; the remaining blocker is runtime proof, not a different code direction.

What I checked:

  • Current main emits stale browser protocol literals: On current main, GatewayConnectParams still types browser Control UI minProtocol and maxProtocol as literal 4, which excludes the current protocol version. (ui/src/ui/gateway.ts:215, 7d1317634e5b)
  • Current main builds stale browser connect params: The browser connect builder sends minProtocol: 4 and maxProtocol: 4 in the WebSocket connect params. (ui/src/ui/gateway.ts:577, 7d1317634e5b)
  • Shared Gateway protocol constants are version 5: The shared protocol module currently defines both PROTOCOL_VERSION and MIN_CLIENT_PROTOCOL_VERSION as 5, so the browser's 4..4 range cannot satisfy the current server. (src/gateway/protocol/version.ts:1, 7d1317634e5b)
  • Gateway rejects ranges excluding the current protocol: The WebSocket connect handler requires the advertised range to include PROTOCOL_VERSION and closes with protocol mismatch otherwise. (src/gateway/server/ws-connection/message-handler.ts:535, 7d1317634e5b)
  • Existing non-browser client already follows the requested pattern: The Node Gateway client defaults its connect range from MIN_CLIENT_PROTOCOL_VERSION and PROTOCOL_VERSION, which supports the PR's approach for the browser client. (src/gateway/client.ts:582, 7d1317634e5b)
  • Current browser test misses protocol field assertions: The current UI gateway node test asserts the connect method and scopes but not the emitted protocol range; the PR adds that missing guardrail. (ui/src/ui/gateway.node.test.ts:337, 7d1317634e5b)

Likely related people:

  • Peter Steinberger: Local blame on the stale browser protocol literals, shared protocol constants, and nearby browser test points to the grafted current-history commit available in this checkout. (role: current implementation carrier / recent area contributor; confidence: medium; commits: dcb416090991; files: ui/src/ui/gateway.ts, ui/src/ui/gateway.node.test.ts, src/gateway/protocol/version.ts)
  • Josh Avant: The existing ClawSweeper review discussion for this PR identified Josh Avant from earlier provenance on the same browser gateway/protocol files; this checkout could not independently validate that older commit because local history is grafted. (role: prior review-provenance routing candidate; confidence: low; commits: 562d460d7599; files: ui/src/ui/gateway.ts, ui/src/ui/gateway.node.test.ts, src/gateway/protocol/version.ts)

Remaining risk / open question:

  • The PR body does not yet show an after-fix browser Control UI to Gateway runtime handshake succeeding on the patched branch.
  • Focused Vitest and UI build proof are not present in the PR body, so CI or maintainer/Testbox validation still needs to cover them.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 7d1317634e5b.

@clawsweeper clawsweeper Bot added P1 High-priority user-facing bug, regression, or broken workflow. impact:crash-loop Crash, hang, restart loop, or process-level availability failure. labels May 17, 2026
@galiniliev
galiniliev force-pushed the bug-018-control-ui-protocol-version branch 2 times, most recently from 587ac07 to 0d334cc Compare May 17, 2026 04:12
@galiniliev
galiniliev force-pushed the bug-018-control-ui-protocol-version branch from 0d334cc to bd24e31 Compare May 17, 2026 04:20
@galiniliev

Copy link
Copy Markdown
Contributor Author

Landing verification for head bd24e31.

Behavior addressed: browser Control UI connect frames now advertise the shared Gateway protocol constants instead of stale protocol 4 literals, so a protocol 5 Gateway is inside the advertised client range.

Local proof:

  • git diff --check
  • rg "minProtocol: 4|maxProtocol: 4" ui/src src/gateway/protocol returned no matches
  • node scripts/run-vitest.mjs ui/src/ui/gateway.node.test.ts passed: 1 file, 27 tests

CI proof:

  • CI run 25981168872 passed on head bd24e31
  • Relevant passing jobs include build-artifacts 76370068490, checks-fast-protocol 76370068530, checks-node-core-ui 76370068666, check 76370142985, check-additional 76370214843, build-smoke 76370214846, and checks-node-core 76370257982

Before evidence:

Evidence after fix:

  • The source now wires ui/src/ui/gateway.ts connect params to MIN_CLIENT_PROTOCOL_VERSION and PROTOCOL_VERSION.
  • The focused regression test asserts the emitted browser connect frame uses those shared constants.

Known proof gap:

  • I did not run a live browser-to-Gateway handshake in this landing pass; maintainer landing accepts the focused unit regression plus green build/protocol/UI CI for this narrow constants wiring fix.

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 impact:crash-loop Crash, hang, restart loop, or process-level availability failure. maintainer Maintainer-authored PR P1 High-priority user-facing bug, regression, or broken workflow. size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Control UI advertises protocol 4 after Gateway moves to protocol 5

1 participant