Skip to content

fix: validate Tool max_retries and timeout parameters - #6375

Merged
hramezani merged 4 commits into
pydantic:mainfrom
isheng-eqi:fix/tool-validate-max-retries-timeout
Jul 9, 2026
Merged

fix: validate Tool max_retries and timeout parameters#6375
hramezani merged 4 commits into
pydantic:mainfrom
isheng-eqi:fix/tool-validate-max-retries-timeout

Conversation

@isheng-eqi

@isheng-eqi isheng-eqi commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #6374

Review in cubic

max_retries < 0 would silently cause unbounded retries. timeout <= 0 causes immediate failures. Add UserError validation for both.
@github-actions github-actions Bot added size: S Small PR (≤100 weighted lines) bug Report that something isn't working, or PR implementing a fix labels Jul 9, 2026
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 760c4870-ced1-4005-a356-f89dd0fe33ca

📥 Commits

Reviewing files that changed from the base of the PR and between ae3f870 and 251f8d9.

📒 Files selected for processing (1)
  • pydantic_ai_slim/pydantic_ai/tools.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • pydantic/logfire (manual)
  • pydantic/pydantic-ai (manual)
  • pydantic/pydantic (auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
  • pydantic_ai_slim/pydantic_ai/tools.py

📝 Walkthrough

Walkthrough

This change adds constructor-time validation to Tool. It imports UserError and raises it when max_retries is negative or timeout is zero or negative. The test suite adds coverage for those failures and for accepted boundary values such as max_retries=0, max_retries=None, and timeout=None.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change to Tool parameter validation.
Description check ✅ Passed The description links the issue, but it omits the template's checklist section and related confirmation items.
Linked Issues check ✅ Passed The changes validate negative max_retries and non-positive timeout at construction time, matching issue #6374.
Out of Scope Changes check ✅ Passed The patch stays focused on Tool parameter validation and the matching tests, with no unrelated changes evident.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a configuration footgun in the Tool API by validating max_retries and timeout at Tool construction time, preventing negative retry budgets and non-positive timeouts that can lead to unbounded retry loops or immediate timeouts.

Changes:

  • Add runtime validation in Tool.__init__ to reject max_retries < 0 and timeout <= 0 (when not None).
  • Add regression tests asserting accepted/rejected values for max_retries and timeout.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
pydantic_ai_slim/pydantic_ai/tools.py Raises UserError on invalid max_retries/timeout values during Tool instantiation.
tests/test_tools.py Adds tests covering the new validation behavior for Tool parameters.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Mirror the `concurrency.py` `_validate_max_running` pattern by moving the
`max_retries`/`timeout` checks into module-level `_validate_max_retries` and
`_validate_timeout` helpers, and validate the local parameters instead of the
assigned instance attributes.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment on lines 586 to 590
self.metadata = metadata
self.timeout = timeout
_validate_max_retries(max_retries)
_validate_timeout(timeout)
self.defer_loading = defer_loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good call — moved both validations to the top of Tool.__init__, before schema generation and any attribute assignment, so invalid max_retries/timeout fail fast without partially initializing the instance. Done in 251f8d9.

Move the `max_retries`/`timeout` validation to the top of `Tool.__init__`,
before schema generation and attribute assignments, so invalid configuration
fails fast without partially initializing the instance.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@hramezani
hramezani enabled auto-merge (squash) July 9, 2026 08:29
@hramezani
hramezani merged commit f60b017 into pydantic:main Jul 9, 2026
69 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Report that something isn't working, or PR implementing a fix size: S Small PR (≤100 weighted lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Tool accepts negative max_retries and non-positive timeout without validation

3 participants