Skip to content

fix(agent-server): bound profile preflight and reject exhausted quotas - #5155

Draft
GDemay wants to merge 1 commit into
OpenHands:mainfrom
GDemay:originator/fix-profile-preflight-budget
Draft

GDemay wants to merge 1 commit into
OpenHands:mainfrom
GDemay:originator/fix-profile-preflight-budget

Conversation

@GDemay

@GDemay GDemay commented Sep 17, 2026 •

Copy link
Copy Markdown

HUMAN:


AGENT:

Why

Profile validation currently accepts an exhausted-budget 429 as valid after inheriting the profile's runtime retry policy. A live HTTP reproduction made 15 provider POSTs before returning valid=true.

Summary

  • Reject exhausted budgets and quotas, including codes retained only in the provider exception chain; continue allowing recoverable rate limits and timeouts.
  • Use a copied LLM with retries/fallback disabled and a 10-second preflight deadline, preserving the saved runtime configuration and subscription/Responses dispatch.
  • Redact credentials and add provider-transport regression coverage plus an authenticated live HTTP test.

Issue Number

Fixes #5100

How to Test

make build
uv run pytest tests/agent_server -n 4 -q
TMPDIR=/tmp uv run pytest tests/cross -q
CI=true TMPDIR=/tmp uv run python -m pytest -m stress --durations=10 tests/agent_server/stress -q
uv run pre-commit run --all-files
uv build --package openhands-agent-server
make test-server-schema

Results: 2,198 Agent Server tests passed; 510 cross-package tests passed with one existing skip; 13 stress tests passed. All repository-wide pre-commit checks (including Pyright) and the package build passed. Independent review and subscription-token re-verification found no remaining material issues. Additional local CI guards passed: deterministic OpenAPI export, schema quality and Swagger validation, deprecation deadlines, persisted-settings compatibility (14 fixtures and eight payloads from published v1.49.1), and REST compatibility using oasdiff 1.19.1 (no breaking changes or additive response type widenings). TMPDIR=/tmp avoids the macOS tmux socket-path limit encountered with the default temporary directory.

The focused end-to-end reproduction is:

uv run pytest tests/cross/test_remote_conversation_live_server.py -k profile_preflight_budget_error_over_http -q

This starts a real authenticated Agent Server and a loopback HTTP provider. Without mocking LiteLLM or the SDK, the provider returns 429 with type: budget_exceeded. Before the fix the endpoint returned valid=true after 15 provider POSTs; after the fix it returns valid=false, a redacted LLMRateLimitError, and exactly one provider POST. The credential is synthetic and no paid inference is used.

Video/Screenshots

This is a headless API change. Before/after reproduction and validation evidence.

Design Doc

Scope and acceptance criteria.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

The deadline bounds the endpoint's wait; an OAuth refresh already executing in a worker thread cannot itself be forcibly stopped. The request/response schema and runtime retry defaults are unchanged. All validation reported in AGENT was performed by coding agents. This draft retains the template's HUMAN placeholder for a human contributor to complete before review starts.

Validate profiles without inheriting runtime retries and reject exhausted budgets or quotas while preserving recoverable rate limits. Cover the real provider transport and authenticated HTTP endpoint, including safe subscription quota diagnostics.

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions

Copy link
Copy Markdown
Contributor

📁 PR Artifacts Notice

This PR contains a .pr/ directory with temporary PR-specific documents. Because this is a fork PR, the workflow will open or update a cleanup PR against main after merge.

@GDemay

GDemay commented Sep 17, 2026 •

Copy link
Copy Markdown
Author

@VascoSch92 local checks pass. please approve the fork ci run.

@ak684 ak684 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.

No blocking code findings. All 126 profile tests and the authenticated HTTP regression passed locally. I also tested this with #5309 and managed-key recovery: 202 focused tests plus the HTTP regression passed. The author still needs to complete the HUMAN note and mark this ready; required CI remains pending.

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.

[Bug]: Profile pre-flight validation reports budget-exceeded keys as valid and blocks ~2 min on retries

2 participants