Panic: UTF-8 string slicing at non-char boundary when processing Chinese characters in agent description

Resolved 💬 3 comments Opened Jan 8, 2026 by user-no-found Closed Jan 8, 2026

Bug Description

Claude Code panics with a UTF-8 string boundary error when processing agent configuration files containing Chinese characters in the description field.

Error Message

thread '<unnamed>' (119699) panicked at /rustc/ed61e7d7e242494fb7057f2657300d9e77bb4fcb/library/core/src/str/mod.rs:833:21:
byte index 52 is not a char boundary; it is inside '务' (bytes 50..53) of `:proposal指定doc-agent、需要文档更新任务。"`
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fatal runtime error: failed to initiate panic, error 5, aborting

Root Cause

The Rust code attempts to slice a UTF-8 string at byte index 52, which falls in the middle of the Chinese character "务" (which occupies bytes 50-52 in UTF-8 encoding). UTF-8 requires slicing only at character boundaries.

Reproduction

  1. Create an agent configuration file (e.g., ~/.claude/agents/doc-agent.md) with Chinese characters in the description:
---
name: doc-agent
description: "文档执行子代理:更新文档、changelog、使用指南。触发条件:proposal指定doc-agent、需要文档更新任务。"
tools: Read, Write, Glob, Grep, WebFetch
model: inherit
---
  1. Use Claude Code in a project that references this agent
  2. The panic occurs when Claude Code processes the file history or agent configuration

Expected Behavior

Claude Code should handle UTF-8 strings correctly by:

  • Using character indices instead of byte indices for string slicing
  • Using safe methods like char_indices() or chars().take(n) for truncation

Suggested Fix

Replace byte-based slicing like:

let slice = &s[..52];  // Unsafe for multi-byte UTF-8

With character-safe alternatives:

// Option 1: Using char_indices
if let Some((idx, _)) = s.char_indices().nth(n) {
    let slice = &s[..idx];
}

// Option 2: Collect chars
let chars: Vec<char> = s.chars().collect();
let slice: String = chars[..n].iter().collect();

Environment

  • OS: Linux (WSL2)
  • Claude Code version: 2.0.76 (based on session logs)
  • Rust version: Unknown (from rustc path in error)

Additional Context

The error also triggers a secondary failure: fatal runtime error: failed to initiate panic, error 5, aborting - suggesting the panic handler itself may have issues, possibly due to FFI boundaries or thread context.

Workaround

Clearing the file-history cache for the affected files temporarily resolves the issue:

find ~/.claude/file-history -name "<file-hash>@*" -delete

However, this is not a permanent solution as the bug will recur when processing new files with multi-byte UTF-8 characters.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗