Repository navigation
PC-5227: wait out guardrail validate budget, don't retry read timeouts - #1967
Draft
al3xanndru wants to merge 1 commit into
Draft
al3xanndru wants to merge 1 commit into
al3xanndru wants to merge 1 commit into
Conversation
…d on read timeout Text-only guardrail validations used the client's default 30 s timeout while the server may take up to 120 s (e.g. when LLMOps PII detection is throttled), and every ReadTimeout was retried with the same input, restarting the server-side work each time. All five attempts timed out and the run failed. Give every validate call a 150 s read timeout (connect stays at 30 s) and stop retrying a read timeout for this call; connect failures, 429/502/503/504/524 and 5xx responses are still retried as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Problem
PC-5227: a pre-execution PII guardrail check made the agent run fail. All five
POST agentsruntime_/api/execution/guardrails/validateattempts ended inhttpx.ReadTimeoutat about 30.05 s each, and the run failed withAGENT_RUNTIME.UNEXPECTED_ERRORafter 168 s. This happened in prd, paid.eus: jobfda68d58-abb3-4c44-8d76-21cf1e2c425aon 2026-10-13 and job81cda36con 2026-10-12. It was found by the triage of SRE-679237.On the server, the same
ValidateGuardrailcalls took 30.1, 120.1, 120.1, 91.6 (200) and 30.0 s while LLMOps PII detection was returning 429s (LLMOPS-3371). So the server did return a verdict, but the client had already given up.Root cause
GuardrailsService.evaluate_guardrailpasses a longer timeout (60 s) only when attachments are present. A text-only check uses the client's defaulttimeout=30.0fromcommon/_http_config.py, which is shorter than the server's 120 s budget.BaseService.requestretries everyhttpx.TimeoutExceptionup toMAX_RETRY_ATTEMPTS = 5. That includesReadTimeout, where the request was already sent and the server is still working on it. Each retry sends the same input again and starts a new server-side PII chain. That adds load to an already throttled quota and times out again for the same reason.Change
_guardrails_service.py: every validate call now useshttpx.Timeout(30.0, read=150.0). Text-only checks, empty-attachment checks and attachment checks all get it. Connect, write and pool keep the 30 s default, and the read budget is above the server's 120 s. This replaces_ATTACHMENT_VALIDATE_TIMEOUT_SECONDS = 60.0, so attachment checks also go from 60 s to 150 s.BaseService.request.retry_with(...). It keepsrequest's wait and stop strategy but swaps the predicate for the newis_retryable_platform_exception_except_read_timeout.common/retry.py: addsis_retryable_platform_exception_except_read_timeout. It behaves likeis_retryable_platform_exceptionbut returnsFalseforReadTimeout.ConnectError,ConnectTimeout,WriteTimeout,PoolTimeout, the retryable statuses (408, 429, 502, 503, 504, 524) and 5xx responses are all still retried.uipath-platform0.2.41 → 0.2.42 and updates the two lockfile entries, following the repo's convention.The worst-case wait is about the same as before: one read of up to 150 s, against five reads of 30 s plus backoff today. The difference is that a server answer that takes 30 to 120 s now arrives in time.
Tests
tests/services/test_guardrails_service.py:TestGuardrailAttachmentTimingis replaced byTestGuardrailValidateTiming:ReadTimeoutraises after exactly one request.ConnectErroris still retried, and the second request succeeds.tests/services/test_retry.py: tests for the new predicate coverReadTimeout,ConnectTimeout,ConnectError, 429 and 400.packages/uipath-platform:pytest→ 1898 passed, 11 skipped.ruff check .andruff format --check .are clean.mypy src testsreports no issues in 233 files.Risks / open questions
ValidateGuardrailrequests ended at 120.1 s with status 0. I couldn't find the limit in the Agents backend (it may be an ingress or gateway timeout). If the real cap is different,_VALIDATE_TIMEOUTshould be adjusted.retry_withis a tenacity attribute that tenacity doesn't type, hence one# type: ignore[attr-defined]. The alternative was a per-call retry switch on the sharedBaseService.request, which seemed too broad for this fix.uipath-agents-python'sexception_mapperhas nohttpx.TimeoutExceptionbranch, so a timeout is still reported asUnknownrather than System.Drafted by the wabbit-dri draft-fixes loop for PC-5227 (draft #1), for a human to review: not ready to merge as is.
🤖 Generated with Claude Code