fix(auto-reply): truncate user-facing text on UTF-16 boundary#97299
Conversation
Use truncateUtf16Safe in agent-runner-execution (message preview) and dispatch-from-config (plan working label) to prevent surrogate pair splitting when non-BMP characters straddle truncation boundaries.
|
Codex review: passed. Reviewed June 27, 2026, 4:38 PM ET / 20:38 UTC. Summary PR surface: Source +2. Total +2 across 2 files. Reproducibility: yes. Current main uses raw Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the narrow helper substitution after exact-head gates; add focused boundary regression assertions only if maintainers want durable coverage before merge. Do we have a high-confidence way to reproduce the issue? Yes. Current main uses raw Is this the best way to solve the issue? Yes. Reusing the existing dependency-free AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c29e1fe764f3. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +2. Total +2 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
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 automerge |
|
🦞✅ Source: What merged:
Automerge notes:
The automerge loop is complete. Automerge progress:
|
…aw#97299) Summary: - The PR imports `truncateUtf16Safe` and uses it for the Codex usage-limit preview and verbose working-label truncation paths in auto-reply. - PR surface: Source +2. Total +2 across 2 files. - Reproducibility: yes. Current main uses raw `slice(0, N)` at both reported user-facing truncation sites, and ... ludes terminal before/after output showing dangling surrogates before the fix and safe truncation after it. Automerge notes: - No ClawSweeper repair was needed after automerge opt-in. Validation: - ClawSweeper review passed for head 74a0a32. - Required merge gates passed before the squash merge. Prepared head SHA: 74a0a32 Review: openclaw#97299 (comment) Co-authored-by: zenglingbiao <[email protected]> Approved-by: takhoffman
…aw#97299) Summary: - The PR imports `truncateUtf16Safe` and uses it for the Codex usage-limit preview and verbose working-label truncation paths in auto-reply. - PR surface: Source +2. Total +2 across 2 files. - Reproducibility: yes. Current main uses raw `slice(0, N)` at both reported user-facing truncation sites, and ... ludes terminal before/after output showing dangling surrogates before the fix and safe truncation after it. Automerge notes: - No ClawSweeper repair was needed after automerge opt-in. Validation: - ClawSweeper review passed for head 74a0a32. - Required merge gates passed before the squash merge. Prepared head SHA: 74a0a32 Review: openclaw#97299 (comment) Co-authored-by: zenglingbiao <[email protected]> Approved-by: takhoffman
…aw#97299) Summary: - The PR imports `truncateUtf16Safe` and uses it for the Codex usage-limit preview and verbose working-label truncation paths in auto-reply. - PR surface: Source +2. Total +2 across 2 files. - Reproducibility: yes. Current main uses raw `slice(0, N)` at both reported user-facing truncation sites, and ... ludes terminal before/after output showing dangling surrogates before the fix and safe truncation after it. Automerge notes: - No ClawSweeper repair was needed after automerge opt-in. Validation: - ClawSweeper review passed for head 74a0a32. - Required merge gates passed before the squash merge. Prepared head SHA: 74a0a32 Review: openclaw#97299 (comment) Co-authored-by: zenglingbiao <[email protected]> Approved-by: takhoffman
…aw#97299) Summary: - The PR imports `truncateUtf16Safe` and uses it for the Codex usage-limit preview and verbose working-label truncation paths in auto-reply. - PR surface: Source +2. Total +2 across 2 files. - Reproducibility: yes. Current main uses raw `slice(0, N)` at both reported user-facing truncation sites, and ... ludes terminal before/after output showing dangling surrogates before the fix and safe truncation after it. Automerge notes: - No ClawSweeper repair was needed after automerge opt-in. Validation: - ClawSweeper review passed for head 74a0a32. - Required merge gates passed before the squash merge. Prepared head SHA: 74a0a32 Review: openclaw#97299 (comment) Co-authored-by: zenglingbiao <[email protected]> Approved-by: takhoffman
Summary
Replace
String.prototype.slice(0, N)withtruncateUtf16Safe()in two auto-reply text truncation paths — agent-runner message preview (497 chars) and plan working label (77 chars) — to prevent broken Unicode when non-BMP characters straddle the truncation boundary.What Problem This Solves
Two user-facing text truncation paths in
src/auto-reply/reply/use raw.slice(0, N)which can split UTF-16 surrogate pairs:message.slice(0, 497)collapsed.slice(0, 77)Both produce dangling surrogates when an emoji or non-BMP CJK character falls at the truncation boundary, displaying garbled
�to users in chat channels.Root Cause
String.prototype.slice()operates on UTF-16 code units, not Unicode code pointsWhy This Fix
truncateUtf16Safeutility fromsrc/shared/utf16-slice.ts(same utility used by sibling PRs fix(shared): use UTF-16 safe truncation in assistant error formatting #97289 and fix(cron): truncate failure alert error text on UTF-16 boundary #97298)User Impact
�when containing emoji near the truncation boundaryEvidence
Terminal proof testing both boundaries (497-char and 77-char) with emoji straddling the cutoff:
Before (
.slice(0, N)): Both boundaries produce dangling surrogates — FAILAfter (
truncateUtf16Safe): Both boundaries truncate safely — PASSReal Behavior Proof
Tests and Validation
pnpm checkpassed