-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Bug Description
a3s-code v1.5.6 panics in core/src/agent.rs when a sub-agent prompt contains multi-byte UTF-8 characters (e.g. Chinese). The Rust worker thread attempts a byte-level slice at a fixed offset that lands inside a multi-byte character, violating Rust's UTF-8 char boundary invariant.
This bug appears to have been introduced or exposed in v1.5.6 (was not observed in earlier versions during the same workflow).
Environment
- a3s-code version: v1.5.6 (Python)
- Platform: Linux
- Trigger:
Orchestrator.spawn_subagent()with a prompt containing Chinese characters
Panic Output
Two independent worker threads panic with the same error pattern:
thread 'a3s-code-worker' panicked at /home/runner/work/Code/Code/core/src/agent.rs:1301:38:
byte index 180 is not a char boundary; it is inside '析' (bytes 179..182) of
`{"agent":"general","description":"Video analysis with scoring adapter","max_steps":15,
"permissive":true,"prompt":"执行视频分析任务,使用 scoring-video-adapter 技能分析以下视频:\n\n视频路径: /mnt/shared-storage-user/zoubo/workspace/Lo`[...]
thread 'a3s-code-worker' panicked at /home/runner/work/Code/Code/core/src/agent.rs:1301:38:
byte index 180 is not a char boundary; it is inside '器' (bytes 179..182) of
`{"goal":"执行视频评分分析任务。视频路径: /mnt/.../机器9/智能网联2451-...mp4。输出目录: /mnt/shared-s`[...]
Key detail: The panic location is agent.rs:1301 — a hardcoded byte offset of 180 is used to slice a JSON string that contains multi-byte UTF-8 characters. Chinese characters are 3 bytes each in UTF-8, so any fixed byte-offset slice will frequently land mid-character.
Minimal Reproduction
from a3s_code import Agent, Orchestrator, SubAgentConfig
agent = Agent.create("config.hcl")
orch = Orchestrator.create(agent=agent)
# Any prompt with Chinese characters (multi-byte UTF-8) triggers the panic
handle = orch.spawn_subagent(SubAgentConfig(
agent_type="general-purpose",
prompt="请分析这个视频文件,路径为:/path/to/视频文件/机器9/测试.mp4",
workspace=".",
permissive=True,
))
try:
result = handle.wait()
print(result)
except Exception as e:
print(e)
# Worker thread panics; sub-agent exits silently after round 1 of thinkingObservable symptom: The sub-agent starts (logs show 🤔 Thinking... (round 1)) but exits immediately after without calling any tools or returning output. The panic is printed to stderr.
Root Cause
agent.rs:1301 performs a byte-index slice (&s[..180] or similar) on a JSON-serialized string that may contain multi-byte characters. This is safe only for pure ASCII. The fix is to use a char-boundary-safe truncation such as:
// Instead of: &s[..180]
// Use:
let truncated = s.char_indices()
.take_while(|(i, _)| *i < 180)
.last()
.map(|(i, c)| &s[..i + c.len_utf8()])
.unwrap_or(&s);Or using the unicode-segmentation crate, or simply s.chars().take(N).collect::<String>().
Impact
- All sub-agent prompts containing non-ASCII characters (Chinese, Japanese, emoji, etc.) will panic
- The panic is silent from Python —
handle.wait()returns an error but the byte-boundary message only appears on stderr - This is a regression in v1.5.6 — the same workflow ran without this panic on v1.5.3/v1.5.4