fix(gateway): keep close reasons valid UTF-8#100045
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as superseded: this PR is a valid draft candidate for the linked gateway UTF-8 close-reason bug, but #100047 now targets the same helper, is open and non-draft, is mergeable/maintainer-editable, and has positive terminal screenshot proof, making it the safer canonical landing path. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Canonical path: Consolidate review and landing on the single proof-positive candidate at #100047, then close the linked issue after one UTF-8-safe helper fix merges. So I’m closing this here and keeping the remaining discussion on #100047. Review detailsBest possible solution: Consolidate review and landing on the single proof-positive candidate at #100047, then close the linked issue after one UTF-8-safe helper fix merges. Do we have a high-confidence way to reproduce the issue? Yes. Current main still uses raw Is this the best way to solve the issue? Yes for the helper-level fix, but this PR is no longer the best landing path. The same issue is covered by a non-draft, proof-positive duplicate PR that can carry the maintainer review instead. Security review: Security review cleared: The diff only changes a gateway string truncation helper and colocated tests; it does not touch secrets, auth policy, dependencies, workflows, package resolution, or other code-execution surfaces. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 6df0fb818d67. |
Closes #99976
What Problem This Solves
Fixes a gateway close-reason truncation bug where a byte slice could split a multibyte UTF-8 character and decode into a replacement character. That replacement could garble the close reason and re-encode over the WebSocket close-frame byte budget.
Why This Change Was Made
Gateway close-reason truncation now chooses a valid UTF-8 code point boundary at or before the byte limit before decoding the sliced buffer. The change keeps the existing fallback behavior for empty close reasons and preserves ASCII close reasons that already fit.
User Impact
Non-ASCII gateway close reasons stay readable and remain within the RFC-safe byte limit.
Evidence
node --import tsx --input-type=module, comparing the exactorigin/maintruncation expression with this branch'struncateCloseReason:136bytes.origin/mainbehavior: tailxxxxxxx�,bytes: 121,containsReplacement: true.xxxxxxxx,bytes: 118,containsReplacement: false.xxxxxx😀,bytes: 120,containsReplacement: false.invalid handshake.src/gateway/server/ws-connection/message-handler.ts:750,:886,:1003,:1546, and:1886all pass gateway handshake/authorization close reasons throughtruncateCloseReason.node scripts/run-vitest.mjs src/gateway/server/close-reason.test.tsTest Files 4 passed (4),Tests 20 passed (20).node scripts/run-vitest.mjs src/gateway/server.auth.default-token.test.tsTest Files 2 passed (2),Tests 38 passed (38).node scripts/run-vitest.mjs src/gateway/client.test.ts -t "gateway rejects"Test Files 2 passed (2),Tests 4 passed | 118 skipped (122).git diff --check origin/main...HEAD.agents/skills/autoreview/scripts/autoreview --mode localautoreview clean: no accepted/actionable findings reportedandoverall: patch is correct (0.93).Real behavior proofrun28715260183, job85155380858, succeeded, but only verified PR problem/evidence text (External PR includes problem context and evidence.); it did not execute this PR's code, so it is not counted as behavioral proof.blacksmithexecutable is not installed.