CLI panics on malformed Retry-After in rate-limit error (Duration::from_secs_f64 overflow)
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
Research direction
Start in codex-rs/codex-api/src/sse/responses.rs at try_parse_retry_after and inspect the seconds branch around lines 509-533, along with the retry-after regex near line 574. Reproduce the oversized value from the issue in an isolated test and verify malformed or overflowing input returns no delay so the normal exponential backoff is used without a panic.
Written by the indexing model from the issue text.
Description
What version of Codex CLI is running?
0.137.0
What subscription do you have?
N/A — source-review finding
Which model were you using?
N/A (platform-independent logic bug)
What platform is your computer?
N/A (platform-independent logic bug)
What terminal emulator and version are you using (if applicable)?
No response
Codex doctor report
not available
What issue are you seeing?
This is a source-review finding (not hit at runtime), reported defensively.
try_parse_retry_after in codex-rs/codex-api/src/sse/responses.rs:509-533 extracts a
number from the server-controlled error.message of a rate_limit_exceeded error
and passes it straight to Duration::from_secs_f64, which panics on overflow / non-finite
values:
let value = value.as_str().parse::<f64>().ok()?; // no digit cap (regex L574)
return Some(Duration::from_secs_f64(value)); // panics on overflow
The regex at L574 — (\d+(?:\.\d+)?) — places no bound on the number of digits, and there
is no length limit on error.message and no clamp on the parsed value. A message such as
"… try again in 99999999999999999999s." (20 digits ≈ 1e20, exceeding u64::MAX seconds
≈ 1.8e19) parses to a finite f64 that overflows Duration, panicking the request task.
This sits directly on the SSE-decoding path, so a single malformed/adversarial upstream
response (e.g. a buggy or hostile custom/OSS provider or proxy) crashes the request.
What steps can reproduce the bug?
The overflow is provable in isolation (matches the exact call on L526):
let value: f64 = "99999999999999999999".parse().unwrap(); // ~1e20
let _ = std::time::Duration::from_secs_f64(value); // panics: "overflow when ..."
End-to-end: have the model endpoint emit an SSE response.failed event with
error.code = "rate_limit_exceeded" and error.message containing
"try again in 99999999999999999999s". try_parse_retry_after then panics instead of
returning a delay.
What is the expected behavior?
A malformed/oversized Retry-After value should never panic; parsing should fail gracefully
and fall back to the normal exponential backoff (the same path as when no delay is parsed).
Additional information
Use the non-panicking constructor and/or clamp the value:
return Duration::try_from_secs_f64(value).ok(); // Rust 1.66+, returns None instead of panicking
Optionally clamp to a sane max (e.g. value.min(MAX_RETRY_AFTER_SECS)) before constructing
the Duration. The ms branch (L528) already uses a saturating as u64 cast and is safe;
only the seconds branch (L526) needs the fix.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- Avg merge
- 1m
- Merged PRs (30d)
- 1k
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
bug CLI windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
macOS sandbox blocks hw.optional.arm64 sysctl, causing Flutter to misdetect Apple Silicon as x64 Openbug CLI sandbox
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug CLI TUI
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
CLI config enhancement skills
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 · 1 comment ·
-
bug triage:deciding
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/otel-arrow#4132 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
bitcoindevkit/bdk-ffi#1125 ·