Skip to content

fix: Retry-After-Ms header silently ignored due to str > int TypeError#766

Open
devteamaegis wants to merge 1 commit into
cohere-ai:mainfrom
devteamaegis:fix/retry-after-ms-string-comparison
Open

fix: Retry-After-Ms header silently ignored due to str > int TypeError#766
devteamaegis wants to merge 1 commit into
cohere-ai:mainfrom
devteamaegis:fix/retry-after-ms-string-comparison

Conversation

@devteamaegis
Copy link
Copy Markdown

@devteamaegis devteamaegis commented May 24, 2026

Bug

_parse_retry_after in src/cohere/core/http_client.py retrieves the Retry-After-Ms header and then compares the raw header string against an integer:

retry_after_ms = response_headers.get("retry-after-ms")  # always a str
if retry_after_ms is not None:
    try:
        return int(retry_after_ms) / 1000 if retry_after_ms > 0 else 0  # ← bug
    except Exception:
        pass

In Python 3, "1000" > 0 raises TypeError: '>' not supported between instances of 'str' and 'int'.
That exception is caught and silently discarded, so the Retry-After-Ms header is always ignored — every response that carries one falls through to Retry-After or exponential back-off instead.

Fix

Convert the header value to int before the comparison:

ms = int(retry_after_ms)
return ms / 1000 if ms > 0 else 0

Reproduction

from cohere.core.http_client import _parse_retry_after
import httpx

headers = httpx.Headers({"retry-after-ms": "2000"})
print(_parse_retry_after(headers))  # None (bug) — should be 2.0

Tests

Added tests/test_http_client.py with 10 unit tests covering positive values, zero, negative values, fractional milliseconds, invalid header content, header priority (Retry-After-Ms vs Retry-After), and the no-header case.


Note

Low Risk
Low risk: narrow bugfix in retry-delay parsing plus unit tests; only affects how backoff delay is computed when retry-after-ms is present.

Overview
Fixes _parse_retry_after to correctly handle retry-after-ms by converting the header string to an int before comparing/clamping, preventing a TypeError that previously caused the header to be silently ignored.

Adds a new tests/test_http_client.py suite covering retry-after-ms and retry-after parsing (valid/invalid values, priority, and no-header cases) to prevent regressions.

Reviewed by Cursor Bugbot for commit 02c2a8f. Bugbot is set up for automated code reviews on this repo. Configure here.

`_parse_retry_after` retrieved the `Retry-After-Ms` response header and
then compared the raw *string* value to an integer with `>`:

```python
return int(retry_after_ms) / 1000 if retry_after_ms > 0 else 0
```

In Python 3, comparing `str > int` raises `TypeError`, which was
silently swallowed by the surrounding `except Exception: pass`.
The practical effect is that every `Retry-After-Ms` header was
completely ignored — the client always fell through to the
`Retry-After` header or exponential back-off instead of honouring
the server-supplied millisecond delay.

Fix: convert to `int` first, then compare.

```python
ms = int(retry_after_ms)
return ms / 1000 if ms > 0 else 0
```

Adds `tests/test_http_client.py` with unit tests that cover positive,
zero, negative, fractional, invalid, and combined header scenarios.
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.

1 participant