Skip to content

SDK does not retry on HTTP 429 rate limit errors #107

Description

@roi-shikler-thenvoi

Problem Summary

When running multiple agents that connect to the Thenvoi platform simultaneously, the agents hit HTTP 429 (Too Many Requests) errors from the AWS ALB. The SDK does not handle this gracefully, causing immediate failures.

Environment

  • SDK: thenvoi (high-level SDK) + thenvoi_rest (auto-generated REST client)
  • Use Case: Starting 5+ agents simultaneously
  • API Endpoint: GET /api/v1/agent/me (called during Agent.start()PlatformRuntime.initialize())

Observed Behavior

  1. Multiple agents start concurrently
  2. Each agent calls GET /api/v1/agent/me during initialization
  3. AWS ALB returns HTTP 429 Too Many Requests with empty body
  4. SDK raises ApiError immediately without retry
  5. Application crashes

Error Response from ALB:

status_code: 429
headers: {'server': 'awselb/2.0', 'content-length': '0', 'connection': 'keep-alive'}
body: (empty)

Root Cause

The thenvoi_rest package (auto-generated by Fern) has retry infrastructure in http_client.py:

  • 429 IS correctly marked as retryable in _should_retry() (line 121-123)
  • Exponential backoff with jitter IS implemented in _retry_timeout() (lines 99-118)
  • BUT max_retries defaults to 0 (line 300 sync, 503 async)

The retry logic exists but is disabled by default.

Recommended Fix

Option A: SDK-level fix (no Fern changes needed)

Pass request_options with retry config to REST API calls:

# In platform_runtime.py
response = await self._link.rest.agent_api.get_agent_me(
    request_options={"max_retries": 3}
)

Option B: Expose retry configuration in Agent.create()

Agent.create(
    adapter=adapter,
    agent_id=agent_id,
    api_key=api_key,
    max_retries=5,  # New parameter
)

Priority

High - This affects any user running multiple agents, which is a core use case.

Workaround

Stagger agent startup:

async def start_agents_with_delay(agents, delay_seconds=1.0):
    for agent in agents:
        await agent.start()
        await asyncio.sleep(delay_seconds)

Activity

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

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions