Skip to content

Fix NPE in Bedrock converseStream when tool use has empty arguments#18783

Open
stefanopace wants to merge 4 commits into
open-telemetry:mainfrom
stefanopace:fix/tool-calls-without-parameters
Open

Fix NPE in Bedrock converseStream when tool use has empty arguments#18783
stefanopace wants to merge 4 commits into
open-telemetry:mainfrom
stefanopace:fix/tool-calls-without-parameters

Conversation

@stefanopace
Copy link
Copy Markdown

@stefanopace stefanopace commented May 18, 2026

Summary

Fixes a NullPointerException in Bedrock Runtime GenAI instrumentation when a model invokes a tool without streaming any tool input JSON (empty accumulated arguments).

This could crash applications using converseStream (including via the Java agent's automatic wrapBedrockRuntimeClient) because the exception was thrown inside the event-stream handler and propagated through the AWS SDK async pipeline.

Problem

On ContentBlockStopEvent, TracingConverseStreamResponseHandler calls deserializeDocument(currentToolArgs.toString()) to parse accumulated tool arguments.

When the model selects a tool but sends no toolUse.input deltas, currentToolArgs is empty. JsonNodeParser.parse("") returns null, and null.visit(DOCUMENT_UNMARSHALLER) throws an NPE. As a result:

  • gen_ai.choice logs are not emitted
  • the streaming response handling can fail and affect the application

Solution

Treat a null JSON node as an empty object document ({}) in deserializeDocument(String), which matches the semantic of a parameterless tool call.

This also protects other call sites that use the same helper:

  • invokeModelWithResponseStream (Anthropic input_json_delta with no partial JSON)
  • Nova tool parsing when input is an empty string in the payload

Test plan

  • Added testConverseStreamToolCallWithEmptyToolArguments in AbstractAws2BedrockRuntimeTest with a WireMock event stream simulating a tool block start/stop without input deltas
  • Asserts gen_ai.user.message and gen_ai.choice log records, including toolCalls with arguments: "{}"
  • ./gradlew :instrumentation:aws-sdk:aws-sdk-2.2:library:testBedrockRuntime passes

Notes

  • Only deserializeDocument(String) is changed; the byte[] overload is unchanged.
  • Fix applies to both library instrumentation and the Java agent (same BedrockRuntimeImpl via wrapBedrockRuntimeClient).

@stefanopace stefanopace requested a review from a team as a code owner May 18, 2026 14:18
Copilot AI review requested due to automatic review settings May 18, 2026 14:18
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 18, 2026

CLA Signed
The committers listed above are authorized under a signed CLA.

@laurit
Copy link
Copy Markdown
Contributor

laurit commented May 22, 2026

@stefanopace are you able to sign the cla?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants