[BUG] Skill activation emits a second `isMeta` message that orphans the Skill `tool_use` → 400 invalid_request (surfaced as "tool use concurrency")

Status Fixed / completed
Reported on v2.1.205
Maintainer reply ✓ Yes — bcherny
Activity 3 comments · opened Jul 9, 2026 · closed Aug 17, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

[BUG] Skill activation emits a second isMeta message that orphans the Skill tool_use → 400 invalid_request (surfaced as "tool use concurrency")

What's Wrong?

Activating a skill via the Skill tool intermittently kills the turn with:

API Error: 400 due to tool use concurrency issues. Run /rewind to recover the conversation.

That user-facing message is misleading. With --debug, the real API error is a plain 400 invalid_request about a broken tool_use/tool_result pairing:

messages.2: `tool_use` ids were found without `tool_result` blocks immediately after: <id>.
Each `tool_use` block must have a corresponding `tool_result` block in the next message.

The orphaned tool_use at messages.2 is the Skill tool call itself.

Root cause

The debug log states it directly:

[INFO]  tool_dispatch_start tool=Skill toolUseId=<id>
[DEBUG] SkillTool returning 2 newMessages for skill skill-creator:skill-creator
[INFO]  tool_dispatch_end tool=Skill toolUseId=<id> outcome=ok
[ERROR] API error: 400 ... messages.2: tool_use ids were found without tool_result blocks immediately after: <id>

SkillTool returns two messages for one activation:

  1. the tool_result for the Skill tool_use, and
  2. a separate isMeta user message containing "Base directory for this skill: …" + the skill's SKILL.md.

When the next request is assembled, that second isMeta message ends up separating the Skill tool_use from its tool_result (the isMeta message's parentUuid skips over the tool_use), so the tool_use is no longer immediately followed by its tool_result. The Messages API rejects the request.

This is the same class of failure as #44596 (an isMeta synthetic message skipping over an orphaned tool_use), and involves the same skill "Base directory" injection described in #64461 — but here it is triggered directly by a single, normal skill activation, not a timeout or a path edge case.

Reproduce

  1. Fresh session (MCP on or off — irrelevant; confirmed with MCP fully disabled).
  2. Ask Claude to activate a skill (repro'd with skill-creator from claude-plugins-official; also fires when skill-creator-primer chains into it).
  3. The turn immediately after the Skill tool call fails with the 400 above.
  4. /rewind is the only recovery — retries stay broken because the malformed message already persists in history.

Debug evidence (two independent repros)

  • Single skill call: request_id req_011CcqZqqC8JaWtM3bgsciVo, orphaned tool_use toolu_01J4BiKZC6wsWLVrEzisc7yK at messages.2, harness line SkillTool returning 2 newMessages for skill skill-creator:skill-creator.
  • Chained (primer → skill-creator): request_id req_011CcqZYbYcvsetFVPtLA5ch, orphaned tool_use toolu_01DbDPEYN398yq6fzCRBoCa2.

Platforms

Reproduces on both Windows (native, PowerShell) and WSL (Linux native), both on 2.1.205 — so this is not platform-, shell-, or install-specific. The two are entirely separate installs with different binaries and different filesystem path formats (C:\… vs /home/…); the "Base directory" path content differs between them yet the failure is identical, confirming the fault is in the cross-platform message-assembly logic, not path handling.

Version

Reproduced on 2.1.205 (native installer) and 2.1.198. In our transcripts every skill-triggered failure is on ≥2.1.198; older builds in the same logs never exercised a skill, so I can't confirm the exact introduction point — but it looks like a recent regression worth bisecting.

Impact

High. Any skill whose activation injects the "Base directory" isMeta message can brick the turn, and because the malformed message persists, the session is unrecoverable without /rewind. The misleading "tool use concurrency" label sends users chasing MCP/parallelism red herrings (see the many unrelated-cause dupes: #40305, #21041, #39818, #51977, #20571).

Suggested fix

Fold the "Base directory / SKILL.md" content into the tool_result block for the Skill call instead of emitting it as a separate isMeta message, so the tool_use → tool_result adjacency the Messages API requires is preserved. Separately, the generic 400 → "tool use concurrency" mapping should be narrowed so this surfaces as the orphaned-tool_use error it actually is.

Related

  • #44596 — same isMeta-orphaning mechanism (different trigger)
  • #64461 — same skill "Base directory" injection

View original on GitHub ↗

3 Comments

sammcj · 3 months ago

Can confirm I have witnessed this myself, and with two other users.

bcherny collaborator · 1 month ago

Thanks for the detailed diagnosis and repro steps. I tried to reproduce this on 2.1.233 (Linux): created two skills under ~/.claude/skills (one with a ~120-line body, one that triggers a follow-up Bash call), then ran ~12 Skill activations across several sessions — sequential activations, re-invocations of the same skill, a skill right after a Bash call in the same turn, and Skill+Bash called in parallel in a single response — all with --debug-file.

No 400 occurred, and grepping the debug logs found zero tool_use ids were found without tool_result errors. Inspecting the session .jsonl, the skill's injected context message consistently lands after the Skill tool's tool_result, not between the tool_use and its result — so the pairing holds, including for parallel tool calls.

A fix for unpaired tool_use blocks (left behind when a tool was interrupted mid-response) shipped in a recent release — see the changelog — which likely covers the intermittent failure you hit.

Closing as fixed in a recent release — if you still see this on 2.1.233 or later, reply to reopen and attach the --debug-file output around the failing request plus the .jsonl snippet around the Skill tool_use, and we'll dig back in.

🤖 Generated with Claude Code

github-actions[bot] · 8 days ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.