[Bug] UTF-8 String Slicing Panic with Multi-byte Characters in Skill Descriptions
Bug Report: UTF-8 String Slicing Panic with Korean Characters
Summary
Claude Code CLI crashes with a Rust panic when processing strings containing Korean (or other multi-byte UTF-8) characters. The panic occurs during string slicing operations that use byte indices instead of character boundaries.
Environment
- Claude Code Version: Latest (as of 2025-12-20)
- OS: macOS Darwin 25.2.0
- Platform: darwin (Apple Silicon)
- Rust Version: Unknown (compiled binary)
Error Message
thread '<unnamed>' (5025078) panicked at /rustc/ed61e7d7e242494fb7057f2657300d9e77bb4fcb/library/core/src/str/mod.rs:833:21:
byte index 6 is not a char boundary; it is inside '의' (bytes 4..7) of `-ADK의 moai-worktree 스킬은 Git Worktree를 `
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fatal runtime error: failed to initiate panic, error 5, aborting
[1] 70176 abort claude --dangerously-skip-permissions -d -r
Steps to Reproduce
- Create a skill or command with Korean text in the description
- Example text:
-ADK의 moai-worktree 스킬은 Git Worktree를... - Run Claude Code CLI with the skill loaded
- CLI crashes with the above panic
Root Cause Analysis
Technical Details
The panic occurs because the code attempts to slice a UTF-8 string at byte index 6, which falls inside a multi-byte Korean character.
UTF-8 Byte Structure:
| Position | Bytes | Character |
|----------|-------|-----------|
| 0 | 1 byte | - |
| 1 | 1 byte | A |
| 2 | 1 byte | D |
| 3 | 1 byte | K |
| 4-6 | 3 bytes | 의 (Korean) |
| 7 | 1 byte | (space) |
The code tries to slice at byte index 6, which is the middle of the Korean character 의 (occupying bytes 4, 5, 6). In Rust, slicing a &str at a non-character-boundary causes a panic.
Problematic Pattern
// This pattern causes the panic:
let slice = &text[0..6]; // Panics if byte 6 is inside a multi-byte char
// Safe alternatives:
// 1. Use char_indices()
let boundary = text.char_indices().nth(n).map(|(i, _)| i).unwrap_or(text.len());
let slice = &text[0..boundary];
// 2. Use floor_char_boundary() (Rust 1.73+)
let safe_index = text.floor_char_boundary(6);
let slice = &text[0..safe_index];
Impact
- Severity: High (causes complete CLI crash)
- Scope: Any user with non-ASCII characters in skill descriptions, command outputs, or file paths
- Affected Languages: Korean, Japanese, Chinese, Emoji, and any multi-byte UTF-8 characters
Suggested Fix
- Replace all byte-based string slicing with character-boundary-aware methods
- Use
str::floor_char_boundary()(Rust 1.73+) orchar_indices()for safe slicing - Add unit tests with multi-byte UTF-8 strings to prevent regression
Workaround
Users can temporarily avoid this issue by:
- Using only ASCII characters in skill descriptions
- Avoiding Korean/Japanese/Chinese text in metadata fields
Additional Context
This occurred while using MoAI-ADK project with Korean skill descriptions. The skill system loads YAML files containing Korean text, which triggers the panic during display or processing.
---
Reported by: GOOS
Date: 2025-12-20
Project: MoAI-ADK (https://github.com/moai-adk)
Environment Info
- Platform: darwin
- Terminal: WarpTerminal
- Version: 2.0.74
- Feedback ID: cd408228-6ebe-4f3a-a900-50675b4d3c37
Errors
[{"error":"Error: NON-FATAL: Lock acquisition failed for /Users/goos/.local/share/claude/versions/2.0.74 (expected in multi-process scenarios)\n at XZR (/$bunfs/root/claude:2430:2165)\n at bUA (/$bunfs/root/claude:2430:1885)\n at processTicksAndRejections
Note: Error logs were truncated.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗