fix(mistral): use truncateUtf16Safe for error text truncation#102539
Conversation
Replace naive .slice(0, maxChars) with truncateUtf16Safe() in truncateErrorText() to prevent surrogate pair splitting in Mistral provider error messages shown to users. Co-Authored-By: Claude <[email protected]>
|
Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 4:37 AM ET / 08:37 UTC. Summary PR surface: Source +1. Total +1 across 1 file. Reproducibility: yes. Source inspection shows current main uses raw slice at the Mistral error-body truncation boundary; a long statusCode/body error with an emoji crossing the 4000-code-unit limit would exercise the dangling-surrogate case. 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:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Keep the narrow Mistral error truncation fix, compute the omitted count from the actual safe prefix length, and add redacted runtime proof or focused regression coverage before merge. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main uses raw slice at the Mistral error-body truncation boundary; a long statusCode/body error with an emoji crossing the 4000-code-unit limit would exercise the dangling-surrogate case. Is this the best way to solve the issue? Mostly yes. Reusing truncateUtf16Safe at the local Mistral error formatting boundary is the right shape, but the suffix should count the actual safe prefix length and the PR still needs after-fix proof. Full review comments:
Overall correctness: patch is correct AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 49a5b6a23575. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +1. Total +1 across 1 file. 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
|
|
Maintainer review complete at exact head Review improvements:
Validation:
Known proof gaps: no live Mistral request was sent because the corrected boundary is the local error adapter after the SDK returns; the installed dependency contract and full adapter path are covered. |
|
Merged via squash.
|
…aw#102539) * fix(mistral): use truncateUtf16Safe for error text truncation Replace naive .slice(0, maxChars) with truncateUtf16Safe() in truncateErrorText() to prevent surrogate pair splitting in Mistral provider error messages shown to users. Co-Authored-By: Claude <[email protected]> * fix(ai): keep Mistral errors UTF-16 safe --------- Co-authored-by: Claude <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
What Problem This Solves
Mistral HTTP error bodies were shortened with a raw UTF-16 code-unit slice. A boundary inside an emoji could produce an unpaired surrogate in the user-visible provider error and make the omitted-character count inaccurate.
Why This Change Was Made
The provider now uses the shared UTF-16-safe truncation helper and computes the omitted count from the actual safe prefix. This preserves the existing 4,000-code-unit cap and error format.
User Impact
Long Mistral error bodies remain valid Unicode and report the exact number of omitted UTF-16 code units. Short errors and ASCII-only errors are unchanged.
Evidence
streamMistral(...).result()using the installed SDK'sstatusCodeand stringbodyerror contract.keeps truncated Mistral error bodies UTF-16 safe with an exact omitted count— 1 passed, 10 skipped.@mistralai/mistralaiinstalled source and declarations forMistralError/SDKErrorbefore adjusting the adapter.🤖 Generated with Claude Code