Skip to content

Fix: propagate max_tokens stop reason instead of throwing internal error#365

Merged
benbrandt merged 3 commits intozed-industries:mainfrom
f1729:fix/235-stop-reason-on-token-exhaustion
Mar 3, 2026
Merged

Fix: propagate max_tokens stop reason instead of throwing internal error#365
benbrandt merged 3 commits intozed-industries:mainfrom
f1729:fix/235-stop-reason-on-token-exhaustion

Conversation

@f1729
Copy link
Contributor

@f1729 f1729 commented Mar 1, 2026

Summary

  • When the Claude SDK reports stop_reason: "max_tokens", the ACP adapter now returns { stopReason: "max_tokens" } instead of throwing a RequestError.internalError (JSON-RPC -32603)
  • Scoped to success and error_during_execution result subtypes only — error_max_turns / error_max_budget_usd still correctly map to max_turn_requests

Problem

When tokens are exhausted, the SDK sends a result message with stop_reason: "max_tokens" and is_error: true. The adapter hit the is_error check first and threw an internal error, so ACP clients never received the stopReason field. Downstream tools like toad saw a JSON-RPC exception instead of a clean stop reason.

Fix

Check stop_reason === "max_tokens" before the is_error throw in the success and error_during_execution branches. Token exhaustion is a normal stop condition, not an internal error.

Test plan

  • Added 5 unit tests covering:
    • success + max_tokens + is_error: false → returns max_tokens
    • success + max_tokens + is_error: true → returns max_tokens (main bug)
    • error_during_execution + max_tokens + is_error: true → returns max_tokens
    • success + null stop_reason → still returns end_turn (no regression)
    • success + is_error: true + non-max_tokens → still throws (no regression)
  • All 100 tests pass
  • Build passes

Fixes #235

🤖 Generated with Claude Code

When the Claude SDK reports stop_reason "max_tokens", the ACP adapter
now returns { stopReason: "max_tokens" } instead of throwing a JSON-RPC
internal error. This allows downstream ACP clients to properly detect
token exhaustion.

Fixes zed-industries#235

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cla-bot cla-bot bot added the cla-signed label Mar 1, 2026
Copy link
Member

@benbrandt benbrandt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@benbrandt benbrandt enabled auto-merge (squash) March 2, 2026 06:10
auto-merge was automatically disabled March 2, 2026 18:57

Head branch was pushed to by a user without write access

@f1729
Copy link
Contributor Author

f1729 commented Mar 2, 2026

@benbrandt got a linter error, please approve again

@benbrandt benbrandt enabled auto-merge (squash) March 3, 2026 11:57
@benbrandt benbrandt merged commit 5c1863d into zed-industries:main Mar 3, 2026
2 checks passed
@f1729 f1729 deleted the fix/235-stop-reason-on-token-exhaustion branch March 3, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ACP adapter does not report a stop reason when out of tokens

2 participants