Skip to content

fix(gateway): use truncateUtf16Safe in WebSocket log formatting#102561

Merged
steipete merged 2 commits into
openclaw:mainfrom
lsr911:fix/utf16-ws-log
Jul 9, 2026
Merged

fix(gateway): use truncateUtf16Safe in WebSocket log formatting#102561
steipete merged 2 commits into
openclaw:mainfrom
lsr911:fix/utf16-ws-log

Conversation

@lsr911

@lsr911 lsr911 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Gateway WebSocket diagnostic previews used raw UTF-16 slices in four paths. A log value containing an emoji at a cutoff could therefore produce an unpaired surrogate in diagnostic output.

Why This Change Was Made

Route all four owned WebSocket log boundaries through the existing truncateUtf16Safe helper, preserving each current limit and suffix without adding a second policy path.

User Impact

Gateway diagnostics remain valid Unicode for string, error, message-object, and compact assistant-event previews.

Evidence

  • Added table coverage for string, Error, and message-object formatting at the 240-code-unit boundary.
  • Added public event-summary coverage at the 160-code-unit compact-preview boundary.
  • Focused WebSocket log suite: 4 files, 64 tests passed.
  • Fresh autoreview: clean, no accepted/actionable findings (0.99).

Files Changed

File Change
src/gateway/ws-log.ts Replace four unsafe diagnostic slices with truncateUtf16Safe.
src/gateway/ws-log.test.ts Add formatting boundary regressions.
src/gateway/ws-log-events.test.ts Add compact event-preview boundary coverage.

🤖 Generated with Claude Code

Replace naive .slice(0, N) with truncateUtf16Safe() at four sites:
- formatForLog() error chain display
- formatForLog() object message display
- formatForLog() string value display
- compactPreview() log compaction

Prevents surrogate pair splitting in gateway WS console logs.

Co-Authored-By: Claude <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: XS triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 9, 2026
@lsr911

lsr911 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@steipete WebSocket log formatting fix — 4 truncation sites in formatForLog() and compactPreview(). Same UTF-16 pattern as the merged PRs.

@clawsweeper

clawsweeper Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 5:44 AM ET / 09:44 UTC.

Summary
The PR replaces four raw UTF-16 slice truncations in gateway WebSocket log formatting with truncateUtf16Safe and adds focused boundary tests.

PR surface: Source +1, Tests +17. Total +18 across 2 files.

Reproducibility: yes. source-level: current main uses raw .slice at the targeted UTF-16 boundaries, and the JavaScript behavior can leave a dangling surrogate when the cutoff lands inside an emoji. I did not run a live gateway session in this read-only review.

Review metrics: none identified.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

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

Rank-up moves:

  • [P1] Add redacted terminal/log/live output or a terminal screenshot showing the WebSocket log formatting path no longer emits a dangling surrogate at the boundary.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body lists tests and autoreview, but no redacted terminal/log/live output or screenshot/video showing the gateway WebSocket log boundary after the fix. The contributor should add proof with private details redacted; updating the PR body should trigger a fresh ClawSweeper review, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] No contributor-supplied after-fix real behavior proof is visible yet; tests and CI do not show that the changed gateway WebSocket log path was exercised in a real setup.

Maintainer options:

  1. Decide the mitigation before merge
    Use the shared UTF-16 truncation helper in this gateway log helper, keep the new focused tests, and merge only after redacted terminal/log/live output or equivalent validation demonstrates the boundary behavior.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] The clear blocker is contributor-provided real behavior proof plus ordinary maintainer review, not a concrete code defect for ClawSweeper to repair.

Security
Cleared: The diff only swaps internal string truncation calls to an existing helper and adds tests; it does not alter dependencies, scripts, permissions, secrets, or execution paths.

Review details

Best possible solution:

Use the shared UTF-16 truncation helper in this gateway log helper, keep the new focused tests, and merge only after redacted terminal/log/live output or equivalent validation demonstrates the boundary behavior.

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

Yes, source-level: current main uses raw .slice at the targeted UTF-16 boundaries, and the JavaScript behavior can leave a dangling surrogate when the cutoff lands inside an emoji. I did not run a live gateway session in this read-only review.

Is this the best way to solve the issue?

Yes, this is the narrowest maintainable fix because it reuses the existing normalization-core helper at the four local truncation sites and now includes focused gateway regression tests. The remaining gap is runtime proof, not a different code shape.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🦪 silver shellfish, so this older rating label is no longer current.

Label justifications:

  • P3: This is a low-risk gateway diagnostic formatting fix for rare surrogate-boundary text, not a user-blocking runtime regression.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body lists tests and autoreview, but no redacted terminal/log/live output or screenshot/video showing the gateway WebSocket log boundary after the fix. The contributor should add proof with private details redacted; updating the PR body should trigger a fresh ClawSweeper review, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +1, Tests +17. Total +18 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 5 4 +1
Tests 1 17 0 +17
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 22 4 +18

What I checked:

  • Repository policy read: The root and gateway-scoped AGENTS.md files were read; the gateway hot-path guide did not block this narrow log-formatting change but informed the caller/test/proof review. (AGENTS.md:1, bb1fa4012ecf)
  • Current main behavior: Current main still uses raw .slice for the targeted formatForLog and compactPreview truncation paths, so the PR is not already implemented on main. (src/gateway/ws-log.ts:121, bb1fa4012ecf)
  • Patch scope: The PR head replaces the four targeted truncations with truncateUtf16Safe and imports only the existing normalization-core helper. (src/gateway/ws-log.ts:120, c301e4edfd37)
  • Regression coverage: The latest PR head adds table coverage for string, Error, and message-like object truncation plus assistant event compact-preview truncation at surrogate boundaries. (src/gateway/ws-log.test.ts:83, c301e4edfd37)
  • Helper contract: truncateUtf16Safe clamps the limit and delegates to sliceUtf16Safe, which avoids returning dangling surrogate halves at slice edges. (packages/normalization-core/src/utf16-slice.ts:43, bb1fa4012ecf)
  • Helper export: The @openclaw/normalization-core/utf16-slice subpath is already exported, so the new import uses an existing package surface. (packages/normalization-core/package.json:47, bb1fa4012ecf)

Likely related people:

  • lsr911: Current-main blame for the gateway log formatter and UTF-16 helper points to ed9ce1c, and recent merged adjacent gateway config truncation work also carries this author. (role: introduced behavior and recent adjacent contributor; confidence: medium; commits: ed9ce1c58438, 8c608ae67485; files: src/gateway/ws-log.ts, packages/normalization-core/src/utf16-slice.ts, src/gateway/server-methods/config.ts)
  • steipete: Live PR metadata shows steipete authored the latest test commit on this PR and merged recent adjacent UTF-16 truncation PRs including the gateway session truncation work. (role: recent reviewer, merger, and adjacent test contributor; confidence: medium; commits: c301e4edfd37, dc013e988c83, ed9ce1c58438; files: src/gateway/ws-log.test.ts, src/gateway/session-utils.ts, src/gateway/session-utils.fs.ts)
  • wm0018: A merged nearby gateway session title and preview truncation PR used the same UTF-16-safe helper direction in gateway code. (role: adjacent gateway UTF-16 contributor; confidence: low; commits: 934dbdbcc755; files: src/gateway/session-utils.ts, src/gateway/session-utils.fs.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 (1 earlier review cycle)
  • reviewed 2026-07-09T08:58:00.778Z sha 884f400 :: needs real behavior proof before merge. :: none

@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. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jul 9, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 9, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jul 9, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Land-ready at exact head c301e4edfd376be8dd0119fbd06d1d0961699a47.

Maintainer review added sibling-path coverage for strings, Errors, and message objects plus public event-summary coverage for compact assistant previews. The focused WebSocket log suite passed (4 files, 64 tests), targeted oxfmt and git diff --check passed, and fresh autoreview completed clean with no accepted/actionable findings (0.99). An unrelated TUI PTY timeout passed on focused rerun; the repository landing wrapper now confirms exact-head hosted CI/Testbox gates passed.

Best-fix verdict: all four arbitrary-value boundaries remain owned by ws-log and share the canonical UTF-16-safe primitive without adding a redundant local wrapper.

@steipete
steipete merged commit d0264de into openclaw:main Jul 9, 2026
169 of 173 checks passed
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 10, 2026
…claw#102561)

* fix(gateway): use truncateUtf16Safe in WebSocket log formatting

Replace naive .slice(0, N) with truncateUtf16Safe() at four sites:
- formatForLog() error chain display
- formatForLog() object message display
- formatForLog() string value display
- compactPreview() log compaction

Prevents surrogate pair splitting in gateway WS console logs.

Co-Authored-By: Claude <[email protected]>

* test(gateway): cover UTF-16-safe WebSocket log bounds

---------

Co-authored-by: Claude <[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

gateway Gateway runtime P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: XS status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants