spring-projects / spring-projects/spring-ai

#3915 This submission may cause a MCP tool execution exception, resulting in the abandonment of all tool results.

Open
#4,423 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
Dominant language
Java
Stars
9.5k
Forks
2.9k
Avg merge
1d 7h
Merged PRs (30d)
6

Description

Bug description
In Spring AI 1.0.2 (with submission #3915), when the LLM attempts to call multiple tools simultaneously, if any one of the tools throws an exception (such as response too large, timeout, etc.), the entire executeToolCalls method fails to handle the exception on a per-tool basis. As a result, all tool responses — including those from successfully completed tools — are discarded.

Environment
Spring AI version: 1.0.2
Java version: 21
Additional Context

Expected behavior
Each tool call should be executed and handled independently. Even if one or more tool calls fail, the results of successfully completed tool calls should be returned to the LLM for further processing.

Related code

    public ToolExecutionResult executeToolCalls(Prompt prompt, ChatResponse chatResponse) {
        Assert.notNull(prompt, "prompt cannot be null");
        Assert.notNull(chatResponse, "chatResponse cannot be null");
        Optional<Generation> toolCallGeneration = chatResponse.getResults().stream().filter((g) -> !CollectionUtils.isEmpty(g.getOutput().getToolCalls())).findFirst();
        if (toolCallGeneration.isEmpty()) {
            throw new IllegalStateException("No tool call requested by the chat model");
        } else {
            AssistantMessage assistantMessage = ((Generation)toolCallGeneration.get()).getOutput();
            ToolContext toolContext = buildToolContext(prompt, assistantMessage);
            InternalToolExecutionResult internalToolExecutionResult = this.executeToolCall(prompt, assistantMessage, toolContext);
            List<Message> conversationHistory = this.buildConversationHistoryAfterToolExecution(prompt.getInstructions(), assistantMessage, internalToolExecutionResult.toolResponseMessage());
            return ToolExecutionResult.builder().conversationHistory(conversationHistory).returnDirect(internalToolExecutionResult.returnDirect()).build();
        }

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at executeToolCalls and trace its call to executeToolCall, using the issue's example as the reproduction scenario. Inspect how multiple tool calls and exceptions are handled, then verify that a failing call does not discard responses from successful calls and that those responses are returned to the LLM.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
ai, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.