Skip to content

fix: coerce string-valued tool arguments to declared scalar types#25731

Open
sanidhyasin wants to merge 1 commit into
open-webui:devfrom
sanidhyasin:fix/native-tool-call-string-arg-coercion
Open

fix: coerce string-valued tool arguments to declared scalar types#25731
sanidhyasin wants to merge 1 commit into
open-webui:devfrom
sanidhyasin:fix/native-tool-call-string-arg-coercion

Conversation

@sanidhyasin

Copy link
Copy Markdown

Pull Request Checklist

Before submitting, make sure you've checked the following:

  • Linked Issue/Discussion: Relates to issue: Builtin tool functions crash with TypeError when models pass numeric parameters as strings via native function calling. #25641
  • Target branch: The pull request targets the dev branch.
  • Description: A concise description of the changes is provided below.
  • Changelog: A changelog entry following Keep a Changelog format is included below.
  • Documentation: No documentation changes required.
  • Dependencies: No new or updated dependencies.
  • Testing: Manual verification performed (see below).
  • No Unchecked AI Code: This PR has undergone human review and manual testing.
  • Self-Review: A self-review of the code has been performed.
  • Architecture: Smart default behaviour; no new settings introduced.
  • Git Hygiene: The PR is atomic, rebased on dev, and contains no unrelated commits.
  • Title Prefix: fix

Changelog Entry

Description

Models using native function calling (function_calling: native) sometimes emit numeric or boolean tool parameters as strings — e.g. count="1" instead of count=1. The builtin tools declare int/Optional[int]/bool/float type hints but never coerced the actual runtime values, so the first comparison or arithmetic on such a value raised:

TypeError: '<' not supported between instances of 'int' and 'str'

For example, search_web crashes on count = max(1, min(count, max_count)) (builtin.py), so the model receives an error response instead of search results.

Fix: coerce string-valued arguments to their declared scalar type inside the shared tool wrapper get_async_tool_function_and_apply_extra_params (backend/open_webui/utils/tools.py). Because every builtin and user-defined tool is invoked through this wrapper, the fix is centralized rather than scattered across individual tools.

The coercion is best-effort and non-intrusive:

  • Only str values are touched; values that already have the correct type are left untouched.
  • int / float / bool (and their Optional[...] forms) are supported. int also tolerates integral floats like "1.0".
  • Booleans accept the usual true/false/1/0/yes/no/on/off spellings.
  • Unparseable values (e.g. count="abc") are passed through unchanged, preserving existing behaviour.
  • get_type_hints failures fall back to no coercion.

Fixed

  • Builtin tool functions no longer crash with TypeError when a model passes numeric/boolean parameters as strings via native function calling (e.g. search_web(count="1")).

Additional Information

  • No new dependencies added.
  • No behavioral change when tools receive correctly-typed arguments — purely defensive coercion for string inputs.

Manual Verification Performed

Validated the coercion against representative tool signatures (search_web(query: str, count: Optional[int]), and a tool with bool/float/int params):

Input Annotation Result
count="1" Optional[int] 1 (and min(count, max_count) no longer raises)
count="3.0" Optional[int] 3
count=None Optional[int] None (unchanged)
count=2 Optional[int] 2 (unchanged)
count="abc" Optional[int] "abc" (unchanged)
case_insensitive="false" bool False
ratio="0.5" float 0.5
query="weather" str "weather" (unchanged)

Contributor License Agreement

Note

Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in.

Native function calling can emit numeric/boolean tool parameters as
strings (e.g. "1" instead of 1). Builtin tools declare int/float/bool
type hints but never coerced the runtime values, so the first comparison
or arithmetic on such a value raised TypeError (e.g. min(count, max_count)
in search_web), crashing the tool call and returning an error to the model.

Coerce string-valued arguments to their declared scalar type in the shared
tool wrapper (get_async_tool_function_and_apply_extra_params), so the fix
covers every builtin and user-defined tool. Coercion is best-effort: only
str values are touched, and unparseable values are passed through unchanged
to preserve existing behaviour.
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.

1 participant