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)

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions