Skip to content

fix: stop silently clobbering tool execution decisions on name collisions#11758

Open
immuhammadfurqan wants to merge 2 commits into
deepset-ai:mainfrom
immuhammadfurqan:fix/hitl-duplicate-name-decision-clobbering
Open

fix: stop silently clobbering tool execution decisions on name collisions#11758
immuhammadfurqan wants to merge 2 commits into
deepset-ai:mainfrom
immuhammadfurqan:fix/hitl-duplicate-name-decision-clobbering

Conversation

@immuhammadfurqan

Copy link
Copy Markdown
Contributor

Related Issues

Proposed Changes:

_apply_tool_execution_decisions is supposed to raise a ValueError when it can't unambiguously match a ToolExecutionDecision to a tool call (multiple tool calls share a name and lack a tool_call_id). The guard only checked not decision_by_id across the entire batch, so if any unrelated tool call elsewhere in the same batch happened to carry an id, the guard was skipped — even though the duplicate-named, id-less calls were still just as ambiguous. Once skipped, the name-based fallback (decision_by_name) silently resolved to whichever decision was last in the dict, applying the wrong arguments to the wrong tool call with no error or warning.

This also affects a subtler case: if one of two same-named calls has an id and the other doesn't, the id-less one still falls back to decision_by_name, which is corrupted by the collision regardless of the other call having an id.

This PR replaces the guard with a check that counts tool-name occurrences across the whole batch and raises whenever an id-less decision's name collides with another decision's name anywhere in the batch — whether or not that other decision has an id.

How did you test it?

Added two regression tests: one for the originally reported case (duplicate id-less names plus an unrelated id-bearing call), and one for the case where one of the two same-named calls has an id and the other doesn't. Ran the full human_in_the_loop test suite (30 passed), ruff check/ruff format, and mypy — all clean.

Notes for the reviewer

None.

Checklist

  • I have read the contributors guidelines and the code of conduct.
  • I have updated the related issue with new insights and changes.
  • I have added unit tests and updated the docstrings.
  • I've used one of the conventional commit types for my PR title: fix:, feat:, build:, chore:, ci:, docs:, style:, refactor:, perf:, test: and added ! in case the PR includes breaking changes.
  • I have documented my code.
  • I have added a release note file, following the contributors guidelines.
  • I have run pre-commit hooks and fixed any issue.

…ions

The ambiguity guard in _apply_tool_execution_decisions only checked
whether *every* decision in the batch lacked a tool_call_id. If any
unrelated tool call in the same batch had an id, the guard was
skipped entirely, even though id-less duplicate-named calls were
still present. The matching fallback (decision_by_name) would then
silently resolve to the wrong decision, applying the wrong arguments
to the wrong tool call with no error.

The guard now checks whether any id-less decision's tool name collides
with another decision anywhere in the batch, regardless of whether
the colliding decision has an id, and raises ValueError in that case.

Fixes deepset-ai#11756
@immuhammadfurqan immuhammadfurqan requested a review from a team as a code owner June 24, 2026 19:50
@immuhammadfurqan immuhammadfurqan requested review from davidsbatista and removed request for a team June 24, 2026 19:50
@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

@immuhammadfurqan is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Jun 24, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added the type:documentation Improvements on the docs label Jun 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  haystack/human_in_the_loop
  strategies.py 516
Project Total  

This report was generated by python-coverage-comment-action

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

Labels

topic:tests type:documentation Improvements on the docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

human_in_the_loop: duplicate tool-call-name ambiguity guard silently skipped, causing wrong decisions to be applied

2 participants