google-gemini / google-gemini/gemini-cli
bug: RetryInfo delay of '0s' is treated as missing, misclassifying retryable rate limits as terminal
- Dominant language
- TypeScript
- Stars
- 107k
- Forks
- 14.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 45
Description
## What happened?
`classifyGoogleError()` parses `RetryInfo.retryDelay` via `parseDurationInSeconds()`, then guards with `if (parsedDelay)` — treating a **successful parse of `"0s"`/`"0ms"` as a failure** because `0` is falsy. `delaySeconds` stays `undefined`, so a `RATE_LIMIT_EXCEEDED` error carrying "retry immediately" semantics falls into the terminal branch instead of the retryable one: retries are aborted and the fallback/credits flow fires for a routine rate limit.
## Affected code
`packages/core/src/utils/googleQuotaErrors.ts:340-345`:
```ts
if (retryInfo?.retryDelay) {
const parsedDelay = parseDurationInSeconds(retryInfo.retryDelay);
if (parsedDelay) { // <-- 0 is falsy
delaySeconds = parsedDelay;
}
}
```
`packages/core/src/utils/googleQuotaErrors.ts:103-113`:
```ts
function parseDurationInSeconds(duration: string): number | null {
// ...
if (duration.endsWith('s')) {
const seconds = parseFloat(duration.slice(0, -1));
return isNaN(seconds) ? null : seconds; // returns 0 for "0s"
}
```
The same truthiness guard recurs at ~line 411 (`retryInfo?.retryDelay && delaySeconds`).
## How can this be reproduced?
Return a 429 with body containing `ErrorInfo { reason: "RATE_LIMIT_EXCEEDED" }` and `RetryInfo { retryDelay: "0s" }`. Observed: `TerminalQuotaError` (terminal). Expected: `RetryableQuotaError` with immediate/small delay.
## What did you expect to happen?
A parsed delay of exactly `0` should be honored ("retry now"), not treated as unparseable.
## Suggested direction
Use the documented sentinel contract: `const parsed = parseDurationInSeconds(...); if (parsed !== null) { delaySeconds = parsed; }` at both occurrences.
---
*Found by source audit on current `main` (commit `5411f113c`); platform-independent. No open issue/PR covering this was found (searched: retry delay rate limit terminal).*
Contributor guide
Research direction
Start in packages/core/src/utils/googleQuotaErrors.ts, reading parseDurationInSeconds() and both retry-delay guards around lines 340-345 and 411. Verify the existing quota-error handling path for a RetryInfo delay of "0s" or "0ms". Done means a successfully parsed zero delay selects RetryableQuotaError rather than TerminalQuotaError without changing invalid-duration handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 85/100