Skip to content

fix: stop the LLM repeating a tool call it was given no cause for - #10109

Merged
tomivirkki merged 1 commit into
mainfrom
ai-tools-generic-error-stops-retry-loop
Sep 14, 2026
Merged

tomivirkki merged 1 commit into
mainfrom
ai-tools-generic-error-stops-retry-loop

Conversation

@tomivirkki

Copy link
Copy Markdown
Member

Description

A DatabaseProvider that throws anything other than a ToolException leaves the LLM with a bare error and nothing to correct, so it sent the same failing query again and again until the turn was spent. Seen with both gpt-4o and gpt-4o-mini against a provider that threw IllegalArgumentException. Repeating the call unchanged can only fail the same way, but a rewritten attempt is still worth one try, because the cause is often something the LLM can avoid by itself, such as an identifier the database reserves.

  • Added guidance to the error that update_chart_data_source, update_chart_configuration and update_grid_data return when they fail for a reason the LLM cannot be told: it now asks for a changed query rather than the same one, and for the failure to be reported if it cannot be changed
  • Kept the cause itself out of the response, as before, so only a ToolException message reaches the LLM
  • Narrowed two existing tests that asserted the whole error string down to what the wording cannot change: that the call reports an error, and that the cause never reaches the LLM

Type of change

  • Bugfix

Note

Nothing enforces the "once more" count, so an LLM that ignores the guidance can still loop. Bounding it properly would mean counting attempts in the controller, which is a bigger change than this fix.

🤖 Generated with Claude Code

A chart or grid data update that failed with anything other than a
ToolException returned a bare error, so the LLM had nothing to correct and
sent the same query again until the turn was spent. The error now asks for
a changed query rather than the same one, and for the failure to be
reported if it cannot be changed. The cause itself still never reaches the
LLM.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@vaadin-review-bot vaadin-review-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed the changes — left 1 comment.

Finding
🧪 No test asserts the retry guidance, and the two tests that could have were loosened in the same PR

@sonarqubecloud

Copy link
Copy Markdown

@tomivirkki
tomivirkki added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit cbf3555 Sep 14, 2026
26 checks passed
@tomivirkki
tomivirkki deleted the ai-tools-generic-error-stops-retry-loop branch September 14, 2026 07:52
tomivirkki added a commit that referenced this pull request Sep 14, 2026
…0109) (CP: 25.3) (#10115)

This PR cherry-picks changes from the original PR #10109 to branch 25.3.
---
#### Original PR description
> ## Description
> 
> A `DatabaseProvider` that throws anything other than a `ToolException`
leaves the LLM with a bare error and nothing to correct, so it sent the
same failing query again and again until the turn was spent. Seen with
both gpt-4o and gpt-4o-mini against a provider that threw
`IllegalArgumentException`. Repeating the call unchanged can only fail
the same way, but a rewritten attempt is still worth one try, because
the cause is often something the LLM can avoid by itself, such as an
identifier the database reserves.
> 
> - Added guidance to the error that `update_chart_data_source`,
`update_chart_configuration` and `update_grid_data` return when they
fail for a reason the LLM cannot be told: it now asks for a changed
query rather than the same one, and for the failure to be reported if it
cannot be changed
> - Kept the cause itself out of the response, as before, so only a
`ToolException` message reaches the LLM
> - Narrowed two existing tests that asserted the whole error string
down to what the wording cannot change: that the call reports an error,
and that the cause never reaches the LLM
> 
> ## Type of change
> 
> - Bugfix
> 
> > [!NOTE]
> > Nothing enforces the "once more" count, so an LLM that ignores the
guidance can still loop. Bounding it properly would mean counting
attempts in the controller, which is a bigger change than this fix.
> 
> 🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Tomi Virkki <tomivirkki@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

4 participants