Skip to content

[Bug]: retry_request misses ConnectTimeout/WriteTimeout and crashes on non-numeric Retry-After #642

Description

@tejajakarulloh

Description

retry_request in src/agentos/channels/_util.py:297 catches (httpx.ConnectError, httpx.ReadTimeout), but httpx.ConnectTimeout (DNS/TLS handshake timeout) is not a subclass of httpx.ConnectError — it inherits from httpx.TimeoutException via a completely separate hierarchy:

  • ConnectErrorNetworkErrorTransportError
  • ConnectTimeoutTimeoutExceptionTransportError

When a channel API call (Slack, Discord, Telegram, webhook) times out during DNS resolution or TLS negotiation, the exception passes through retry_request without any retry/backoff — the caller gets an unhandled crash instead of a resilient retry.

Similarly, WriteTimeout and PoolTimeout (both TimeoutException subclasses) are also not caught.

Additionally, the Retry-After header is parsed via a bare float() call (_util.py:287). Per RFC 7231 §7.1.3, Retry-After may contain an HTTP-date string (e.g. Wed, 21 Oct 2026 07:28:00 GMT) instead of delay-seconds. A non-numeric value causes a ValueError crash in the retry loop.

Steps to Reproduce

import httpx
# ConnectTimeout is NOT caught by (ConnectError, ReadTimeout)
try:
    raise httpx.ConnectTimeout("dns timed out")
except (httpx.ConnectError, httpx.ReadTimeout):
    print("caught")  # never reached
except httpx.TimeoutException:
    print("missed by retry_request")  # this fires

Expected Behavior

All transient timeout types should be retried with exponential backoff, and non-numeric Retry-After values should fall back to the standard backoff delay instead of crashing.

Environment

  • Python 3.12
  • httpx (current pinned version)

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: channelsShared channel runtime, dispatch, routing, and access policypriority: p2Medium priority: important but has a workaround or limited impactstatus: needs reviewImplementation exists and needs maintainer reviewtype: bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions