claude-code - 💡(How to fix) Fix [BUG] Agent Teams: non-ASCII teammate/team_name causes "Header has invalid value" API error via x-claude-code-agent-id

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

Per-teammate transcripts at ~/.claude/projects/<project>/<lead_sid>/subagents/agent-<id>.jsonl:

| Teammate name | Charset | First assistant message | |-----------------|-----------------|------------------------------------------ --------------------------| | pure-ascii-1 | ASCII | tool_use SendMessage ✅ | | under_score_2 | ASCII + _ | tool_use SendMessage ✅ | | Dot.Period.3 | ASCII + . | tool_use SendMessage ✅ | | 测试甲 | Chinese | API Error: ... invalid value: '测试甲@bug-charset-test' ❌ | | botMixed中 | ASCII + Chinese | same template ❌ | | caféAccent | Latin-1 (é) | same template ❌ | | emoji-bot-🤖 | Emoji | same template ❌ |

Failing transcripts share model: "<synthetic>", stop_reason: "stop_sequence", isApiErrorMessage: true, zero tokens. Passing transcripts show model: "claude-opus-4-7" with a normal tool_use content block. The only variable between the two code paths is the header value — same backend, same session, same model, same prompt template.

Root Cause

  • Any non-English / CJK / emoji team or agent name breaks Agent Teams entirely.
    • The zombie teammate cannot receive shutdown_request because shutdown routing itself goes through an LLM turn. Only recovery: manually edit ~/.claude/teams/<team>/config.json to remove the member, then TeamDelete.
    • The error surfaces only inside the subagent transcript, not the parent session UI — diagnosis is painful for non-developer users.

Fix Action

Fix / Workaround

Workaround

Code Example

Per-teammate transcripts at
  `~/.claude/projects/<project>/<lead_sid>/subagents/agent-<id>.jsonl`:

  | Teammate name   | Charset         | First assistant message
                            |
  |-----------------|-----------------|------------------------------------------
  --------------------------|
  | pure-ascii-1    | ASCII           | tool_use SendMessage                             |
  | under_score_2   | ASCII + `_`     | tool_use SendMessage                             |
  | Dot.Period.3    | ASCII + `.`     | tool_use SendMessage                             |
  | 测试甲           | Chinese         | API Error: ... invalid value:
  '测试甲@bug-charset-test'|
  | botMixed中      | ASCII + Chinese | same template ❌
                             |
  | caféAccent      | Latin-1 (`é`)   | same template ❌
                             |
  | emoji-bot-🤖    | Emoji           | same template ❌
                             |

  Failing transcripts share `model: "<synthetic>"`, `stop_reason:
  "stop_sequence"`, `isApiErrorMessage: true`, zero tokens. Passing transcripts
  show `model: "claude-opus-4-7"` with a normal `tool_use` content block. The
  only variable between the two code paths is the header value — same backend,
  same session, same model, same prompt template.
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

When spawning a teammate via Agent({team_name, name, ...}) or creating a team via TeamCreate({team_name, ...}) where either team_name or name contains any non-ASCII character (CJK, emoji, Latin-1 accented like é), the client sends the unencoded value <name>@<team_name> in the HTTP header x-claude-code-agent-id.

HTTP header values are restricted to ASCII (RFC 7230), so the upstream immediately returns:

  API Error: Header 'x-claude-code-agent-id' has invalid value:

'<name>@<team_name>'

The teammate's every wake produces a <synthetic> assistant message containing only that error, then emits an idle_notification. The agent appears alive but can never execute a tool call — it's a zombie that consumes mailbox messages without responding.

What Should Happen?

(a) The client encodes the header value (percent-encoding or RFC 8187 extended notation) so non-ASCII team/agent names work transparently, or

(b) TeamCreate and Agent spawn validate the input client-side and reject non-ASCII names with a clear error before spawning — preventing the unrecoverable zombie state where the teammate exists but every LLM call returns "Header has invalid value".

Error Messages/Logs

Per-teammate transcripts at
  `~/.claude/projects/<project>/<lead_sid>/subagents/agent-<id>.jsonl`:

  | Teammate name   | Charset         | First assistant message
                            |
  |-----------------|-----------------|------------------------------------------
  --------------------------|
  | pure-ascii-1    | ASCII           | tool_use SendMessage ✅
                             |
  | under_score_2   | ASCII + `_`     | tool_use SendMessage ✅
                             |
  | Dot.Period.3    | ASCII + `.`     | tool_use SendMessage ✅
                             |
  | 测试甲           | Chinese         | API Error: ... invalid value:
  '测试甲@bug-charset-test'|
  | botMixed中      | ASCII + Chinese | same template ❌
                             |
  | caféAccent      | Latin-1 (`é`)   | same template ❌
                             |
  | emoji-bot-🤖    | Emoji           | same template ❌
                             |

  Failing transcripts share `model: "<synthetic>"`, `stop_reason:
  "stop_sequence"`, `isApiErrorMessage: true`, zero tokens. Passing transcripts
  show `model: "claude-opus-4-7"` with a normal `tool_use` content block. The
  only variable between the two code paths is the header value — same backend,
  same session, same model, same prompt template.

Steps to Reproduce

  1. Enable Agent Teams: export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1

  2. In an interactive Claude Code session, run: TeamCreate({ team_name: "test-ascii" }) Agent({ team_name: "test-ascii", name: "中文worker", prompt: "say hi" })

  3. The teammate spawns successfully, but every LLM call fails with: API Error: Header 'x-claude-code-agent-id' has invalid value: '中文worker@test-ascii'

Reproduces identically with emoji-🤖, café, or any non-ASCII string in name. Also reproduces with an ASCII name if team_name itself contains non-ASCII.

Claude Model

Opus

Is this a regression?

No, this never worked

Last Working Version

No response

Claude Code Version

2.1.139

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Suggested fix

Encode the value before assigning to the header. Two options:

  • Simple: percent-encode the value (encodeURIComponent) on the client; decode on the gateway. Backward compatible since ASCII bytes are unchanged.
  • RFC 8187: use the extended-notation form x-claude-code-agent-id*=UTF-8''<percent-encoded> next to the legacy ASCII header. Requires server cooperation.

If neither is feasible, at least validate on TeamCreate / Agent spawn and reject non-ASCII names client-side with a clear error message, instead of producing an unrecoverable zombie at first LLM call.

Impact

  • Any non-English / CJK / emoji team or agent name breaks Agent Teams entirely.
  • The zombie teammate cannot receive shutdown_request because shutdown routing itself goes through an LLM turn. Only recovery: manually edit ~/.claude/teams/<team>/config.json to remove the member, then TeamDelete.
  • The error surfaces only inside the subagent transcript, not the parent session UI — diagnosis is painful for non-developer users.

Workaround

Restrict team_name and teammate name to [A-Za-z0-9._-]. I deployed a local PreToolUse hook on Agent|TeamCreate matchers that rejects non-ASCII inputs before spawn.


Happy to share the full transcript files or a minimal reproduction script.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING