fix(http-body): keep emoji / surrogate pairs intact during error body truncation#101612
fix(http-body): keep emoji / surrogate pairs intact during error body truncation#101612maweibin wants to merge 1 commit into
Conversation
… truncation Use Array.from() to count full code points instead of UTF-16 code units, preventing lone surrogates in diagnostic output. Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as superseded: the useful HTTP response-snippet UTF-16 fix is covered by the open maintainer-labeled sweep at #101654, which uses the shared helper and adds the missing response-snippet regression test. This standalone branch still changes exported Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Canonical path: Use #101654 as the canonical landing path because it preserves cap semantics, adds the focused response-snippet test, and keeps contributor credit. So I’m closing this here and keeping the remaining discussion on #101654. Review detailsBest possible solution: Use #101654 as the canonical landing path because it preserves cap semantics, adds the focused response-snippet test, and keeps contributor credit. Do we have a high-confidence way to reproduce the issue? Yes, source inspection gives a high-confidence reproduction path: current main truncates Is this the best way to solve the issue? No. This branch avoids lone surrogates but changes an exported cap to code points; the helper-based sweep is the better fix because it preserves the existing UTF-16 cap and adds a response-snippet regression test. Security review: Security review cleared: The diff only changes TypeScript string truncation and adds no dependency, workflow, secret, permission, or code-execution surface. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 60f0749b7fb3. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Thanks @maweibin. The useful behavior from this PR was consolidated with the sibling UTF-16 boundary fixes into #101654 and landed on The landed fix uses the existing |
What Problem This Solves
snippetErrorBodyinsrc/infra/http-body.tstruncates text with.slice()which counts UTF-16 code units. When a surrogate-pair character (emoji) straddles the cut boundary,.slice()produces a lone surrogate (e.g.\ud83d) that renders as `` in terminal output.This is user-visible: the truncated text reaches user-facing CLI, status, or log output, so any content containing emoji near the 315-character boundary can hit this.
Why This Change Was Made
Replace
.slice()withtruncateUtf16Safe()from@openclaw/normalization-core/utf16-sliceso the truncation counts full code points instead of UTF-16 code units. This matches the already-merged PR #101517 (session-cost-usage.ts) and the canonicalshortenTexthelper insrc/commands/text-format.ts:5.User Impact
Users will no longer see `` replacement characters in this output when emoji appear near truncation boundaries. Existing column width / character caps are preserved — the broken surrogate is dropped cleanly rather than rendered as a replacement character.
Evidence
Real environment tested: local OpenClaw source checkout, Node v24.13.1, PR head.
Exact steps after this patch:
Evidence after fix:
Observed result after fix:
truncateUtf16Safepreserves full code points; no lone surrogate reaches output. The broken surrogate pair is dropped cleanly rather than producing ``.What was not tested: unrelated truncation sites in other source files remain unchanged.
Regression Test Plan
Includes a focused regression test that verifies surrogate pair preservation at the truncation boundary.
AI-assisted.