claude-code - 💡(How to fix) Fix Server-side tool (server_tool_use) emitted but no result returned; response reports stop_reason: end_turn

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…

A server-side tool (advisor) was invoked 14 times in a single session. Twice it worked (response stop_reason: tool_use, an advisor_tool_result returned). The other 12 times the assistant response contained a server_tool_use block named advisor but reported stop_reason: end_turn and returned no tool result — the tool never ran and the turn ended silently.

A response that emits a server_tool_use block yet finalizes as stop_reason: end_turn with no corresponding result is self-inconsistent: a server_tool_use block should accompany stop_reason: tool_use. That self-inconsistency is the bug.

User-visible symptom: the assistant says it's calling the tool, then just stops — repeated 12× in one session, including 5× within a single user turn.

Error Message

  • Actual (12×): the server_tool_use block is present, no result is produced, and the response reports stop_reason: end_turn. Silent — no error surfaced to the user.
  • User interrupting a slow call — no interrupted: true anywhere in the transcript, no abort/error records; queued-message records are unrelated in time.
  1. If a server tool can't be serviced, return an explicit error result block rather than a tool-block-without-result + end_turn.

Root Cause

A server-side tool (advisor) was invoked 14 times in a single session. Twice it worked (response stop_reason: tool_use, an advisor_tool_result returned). The other 12 times the assistant response contained a server_tool_use block named advisor but reported stop_reason: end_turn and returned no tool result — the tool never ran and the turn ended silently.

A response that emits a server_tool_use block yet finalizes as stop_reason: end_turn with no corresponding result is self-inconsistent: a server_tool_use block should accompany stop_reason: tool_use. That self-inconsistency is the bug.

User-visible symptom: the assistant says it's calling the tool, then just stops — repeated 12× in one session, including 5× within a single user turn.

RAW_BUFFERClick to expand / collapse

Summary

A server-side tool (advisor) was invoked 14 times in a single session. Twice it worked (response stop_reason: tool_use, an advisor_tool_result returned). The other 12 times the assistant response contained a server_tool_use block named advisor but reported stop_reason: end_turn and returned no tool result — the tool never ran and the turn ended silently.

A response that emits a server_tool_use block yet finalizes as stop_reason: end_turn with no corresponding result is self-inconsistent: a server_tool_use block should accompany stop_reason: tool_use. That self-inconsistency is the bug.

User-visible symptom: the assistant says it's calling the tool, then just stops — repeated 12× in one session, including 5× within a single user turn.

Environment

  • Claude Code CLI: 2.1.158
  • Model: claude-opus-4-8 (1M-context variant)
  • OS: Linux 6.18 (aarch64)
  • Tool: a no-parameter server-side tool (server_tool_use); its result is produced API-side within the same response

Evidence (grouping-independent)

Reading each record that carries a server_tool_use block, by its own stop_reason:

stop_reason on the tool-call recordresult returned?count
tool_useyes2 / 2
end_turnno12 / 12

Zero exceptions across the session. This is read per-record and does not depend on how response blocks are grouped.

Important caveat (for accuracy): end_turn is a correlate, not a proven cause of non-execution. In the same anomalous responses, client-side tool_use blocks (e.g. Bash, Read, Edit) also carried stop_reason: end_turn and did execute and return results. So end_turn alone does not block tool execution — it co-occurs specifically with the server-side tool's missing result. The reportable anomaly is the combination: server_tool_use block present + no server-produced result + end_turn.

Expected vs actual

  • Expected: a response containing a server_tool_use block returns its result in that response and reports stop_reason: tool_use (as the 2 successes did).
  • Actual (12×): the server_tool_use block is present, no result is produced, and the response reports stop_reason: end_turn. Silent — no error surfaced to the user.

What we ruled out (so you don't chase these)

All falsified by live experiment or by timestamp in the originating session:

  • Permission mode auto — a separate session running in auto calls the same tool successfully.
  • Mid-session settings re-read / mode transition — forcing a settings re-read then calling the tool resolved normally.
  • A user-installed Stop hook / settings edits — these postdate the first failure by 23+ minutes; the failures predate them.
  • User interrupting a slow call — no interrupted: true anywhere in the transcript, no abort/error records; queued-message records are unrelated in time.
  • Model failing to emit the call — the server_tool_use block is present all 14 times; the model emitted it every time.

Leading open direction (not asserted)

Within the affected session the failures begin as a hard flip after one success and never recover, while the same tool works in other sessions — consistent with server-side, session-scoped state, but unproven.

Notes for whoever re-checks a transcript

  • Group response blocks by the API response id (message.id), not by usage (input_tokens/output_tokens is not response-unique — it repeats across responses).
  • The stop_reason finding above is read per-record and is grouping-independent.

Impact & ask

Silent failure: the model re-emits the call and may invent false self-explanations, wasting whole turns. Any server-side tool could be affected the same way.

  1. Investigate why a server_tool_use block is emitted in a response that produces no server-tool result and finalizes as stop_reason: end_turn.
  2. If a server tool can't be serviced, return an explicit error result block rather than a tool-block-without-result + end_turn.

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

claude-code - 💡(How to fix) Fix Server-side tool (server_tool_use) emitted but no result returned; response reports stop_reason: end_turn