Skip to content
This repository was archived by the owner on Jun 3, 2026. It is now read-only.

fix: throw MaxTokensError when contentBlockStop carries truncated tool_use JSON#1100

Open
serhiizghama wants to merge 2 commits into
strands-agents:mainfrom
serhiizghama:fix/maxtokens-error-on-truncated-tool-use-json
Open

fix: throw MaxTokensError when contentBlockStop carries truncated tool_use JSON#1100
serhiizghama wants to merge 2 commits into
strands-agents:mainfrom
serhiizghama:fix/maxtokens-error-on-truncated-tool-use-json

Conversation

@serhiizghama

Copy link
Copy Markdown

Problem

When a Bedrock model hits its token limit mid-tool-call, the stream emits contentBlockStop before messageStop. At that point JSON.parse fails on the incomplete input, throwing a SyntaxError — before the subsequent messageStop { stopReason: 'maxTokens' } is processed. The SyntaxError propagates to the caller as a generic ModelError, hiding the MaxTokensError that callers need to recover from:

try {
  await agent.invoke(...)
} catch (e) {
  if (e instanceof MaxTokensError) { /* never reached */ }
  // Caller sees opaque SyntaxError wrapped in ModelError
}

Reported in issue strands-agents/harness-sdk#2451.

Solution

In streamAggregated, defer the SyntaxError instead of throwing it immediately:

  1. Save the error in pendingParseError and let the loop continue to consume the remaining stream events.
  2. After the loop, if pendingParseError is set:
    • If finalStopReason === 'maxTokens' → throw MaxTokensError (truncation by token limit).
    • Otherwise → re-throw the original SyntaxError (genuinely malformed JSON from the model).

Testing

  • Updated the existing test that was asserting the old (incorrect) behavior: now it expects MaxTokensError when contentBlockStop arrives with truncated JSON and stopReason === 'maxTokens'.
  • Added a new test for the non-maxTokens path: malformed JSON with stopReason === 'endTurn' still surfaces ModelError(cause: SyntaxError).

When the model hits its token limit mid-tool_use, the stream emits
contentBlockStop before messageStop. The JSON parse fails with
SyntaxError on the truncated input, but the stop reason is maxTokens.

Defer the SyntaxError instead of throwing immediately, let the stream
complete, then raise MaxTokensError if stopReason === maxTokens — or
re-raise the original SyntaxError otherwise.

Closes #1061
@strands-agent

Copy link
Copy Markdown
Collaborator

This repository has been merged into the strands-agents/harness-sdk monorepo and will be archived shortly. All new development happens there.

If this PR is still relevant, please recreate it against the monorepo. The code now lives under strands-ts/. Full commit history was preserved, so your base should be findable.

Apologies for the disruption, and thank you for contributing!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants