fix(channels): keep inbound log previews UTF-16 safe#102407
Conversation
The matrix inbound verbose preview used bodyText.slice(0, 200) before logging. When a supplementary-plane character (emoji, extended CJK) straddles the 200th code unit, the slice splits its surrogate pair and emits a lone surrogate into the verbose log line. Lone surrogates corrupt JSON log serialization, break terminal rendering, and crash UTF-8-validating log shippers. Use the shared truncateUtf16Safe helper (already used by the mattermost sibling monitor after openclaw#101630) to keep complete surrogate pairs intact. No behavior change for ASCII input; the preview is still capped at 200 code units. Co-Authored-By: Claude <[email protected]>
|
Codex review: needs maintainer review before merge. Reviewed July 9, 2026, 1:12 AM ET / 05:12 UTC. Summary PR surface: Source +1, Tests +49. Total +50 across 2 files. Reproducibility: yes. from source inspection: current 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 Matrix verbose-log helper fix after normal maintainer review and refreshed exact-head or merge-head validation; leave broader preview cleanup to separate, path-specific work. Do we have a high-confidence way to reproduce the issue? Yes, from source inspection: current Is this the best way to solve the issue? Yes. Using the existing plugin SDK AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 624dfa6cf6dc. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +1, Tests +49. Total +50 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
Review history (2 earlier review cycles) |
- Avoid String.prototype.isWellFormed (ES2024 lib): use the encodeURIComponent well-formedness probe instead, which works on the project's TS lib target. - Replace literal string concatenation with template strings to satisfy the no-useless-concat lint rule. No behavior change in the assertions. Co-Authored-By: Claude <[email protected]>
|
Land-ready verification at exact head
No changelog entry is required because this only corrects internal verbose-log formatting. |
|
Merged via squash.
|
* fix(matrix): truncate inbound preview on UTF-16 code-point boundary The matrix inbound verbose preview used bodyText.slice(0, 200) before logging. When a supplementary-plane character (emoji, extended CJK) straddles the 200th code unit, the slice splits its surrogate pair and emits a lone surrogate into the verbose log line. Lone surrogates corrupt JSON log serialization, break terminal rendering, and crash UTF-8-validating log shippers. Use the shared truncateUtf16Safe helper (already used by the mattermost sibling monitor after openclaw#101630) to keep complete surrogate pairs intact. No behavior change for ASCII input; the preview is still capped at 200 code units. Co-Authored-By: Claude <[email protected]> * test(matrix): fix inbound-preview test for lint and lib target - Avoid String.prototype.isWellFormed (ES2024 lib): use the encodeURIComponent well-formedness probe instead, which works on the project's TS lib target. - Replace literal string concatenation with template strings to satisfy the no-useless-concat lint rule. No behavior change in the assertions. Co-Authored-By: Claude <[email protected]> * fix(channels): keep inbound log previews UTF-16 safe * test(line): type verbose preview fixtures --------- Co-authored-by: Claude <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
What Problem This Solves
Matrix, Line, and Telegram verbose inbound previews used raw
String.prototype.slicelimits. A supplementary-plane character crossing one of those UTF-16 code-unit boundaries produced a lone surrogate in diagnostic output. Telegram's reply-context preview had the same defect at its 120-unit limit.Why This Change Was Made
truncateUtf16Safehelper at every affected channel-owned logging boundary.User Impact
Verbose channel logs no longer contain malformed lone surrogates when emoji or other astral characters cross a preview boundary. ASCII output, routing, delivery, prompts, and configuration are unchanged.
Linked context
Sibling fix: #101630.
Evidence
Exact head:
cd7e34fe4857102133b9df9ee6e6095441f6de33oxfmtandgit diff --check: passed.The regression inputs place the high surrogate of an emoji exactly at each production preview limit and assert the complete emitted log line. The safe result backs up one code unit instead of emitting a malformed half-pair.
Real behavior proof
Risk checklist