Panic: UTF-8 byte boundary errors when rendering CJK text
Bug Description
Claude Code CLI crashes with Rust panics when rendering content containing Chinese (CJK) characters. Multiple crashes at different string positions indicate a systemic UTF-8 handling issue.
Error Messages
Crash 1:
thread '<unnamed>' panicked at library/core/src/str/mod.rs:833:21:
byte index 11 is not a char boundary; it is inside '职' (bytes 9..12)
fatal runtime error: failed to initiate panic, error 5, aborting
zsh: abort claude
Crash 2:
thread '<unnamed>' panicked at library/core/src/str/mod.rs:833:21:
byte index 4 is not a char boundary; it is inside '里' (bytes 2..5)
fatal runtime error: failed to initiate panic, error 5, aborting
zsh: abort claude
Analysis
- Both crashes occur at Rust's
str::mod.rs:833(string slicing) - Different Chinese characters trigger the panic at different byte positions
- This indicates a common text truncation/display function has the bug
- The issue appears during CLI startup when processing CLAUDE.md
Root Cause
Byte-based string slicing without checking UTF-8 character boundaries. CJK characters are 3 bytes in UTF-8, so byte-index slicing frequently lands mid-character.
Reproduction
- Create a CLAUDE.md containing Chinese text (especially in markdown tables)
- Run
claudein the directory - CLI crashes during startup or conversation
Environment
- OS: macOS Darwin 24.6.0
- Claude Code: Latest version
Suggested Fix
Use character-aware string operations:
.chars().take(n)instead of&s[..n]- Check
s.is_char_boundary(n)before slicing - Use
s.floor_char_boundary(n)(Rust 1.80+) for safe truncation
Additional Information
The crash also occurs during active conversation, not just on startup:
- Mid-conversation crash: While editing/inserting content during a conversation, the CLI crashed
- Resume crash: Attempting to use
/resumeto restore the session also triggers the same panic
This indicates the bug affects multiple code paths:
- CLAUDE.md parsing (startup)
- Conversation rendering (during chat)
- Session restoration (
/resume)
The issue is more pervasive than initially reported - essentially any text display/truncation operation involving CJK characters can trigger the panic.
Same here: byte index 14 is not a char boundary; it is inside '息' (bytes 12..15)
This is a classic UTF-8 string slicing bug in Rust - the code attempted to slice a string at byte position 14, which falls in the middle of the Chinese character '息' (which spans bytes 12-15). Chinese characters are 3 bytes in UTF-8, and the code incorrectly assumed it could slice at any byte position.
thread '粘稠的窒息。浓云压顶的夜空没有星月,唯有远方闪电在云层深处游走,瞬间照亮荒原上枯树狰狞的枝桠,又迅速被黑暗吞没。
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
fatal runtime error: failed to initiate panic, error 5, aborting
Aborted (core dumped