Skip to content

Interactions retries ignore the documented initial_delay and max_delay defaults #3317

Open

Description

@chrikrah

client.interactions backs off half as long as client.models when initial_delay and max_delay are left unset, so the same HttpRetryOptions give two different retry schedules in one client.

Repro at afb10e8 (3.0.0), with no network and no real key:

import time, httpx2
from google import genai
from google.genai import types

stamps = []
def handler(request):
    stamps.append(time.monotonic())
    return httpx2.Response(503, json={"error": {"code": 503, "message": "unavailable", "status": "UNAVAILABLE"}})

def gaps():
    return [round(b - a, 1) for a, b in zip(stamps, stamps[1:])]

retry = types.HttpRetryOptions(attempts=4, jitter=0)  # jitter=0 keeps the gaps exact; delays left unset
client = genai.Client(
    api_key="test",
    http_options=types.HttpOptions(
        retry_options=retry, httpx_client=httpx2.Client(transport=httpx2.MockTransport(handler))
    ),
)
for name, call in [
    ("models.generate_content", lambda: client.models.generate_content(model="gemini-3.8-flash", contents="hi")),
    ("interactions.create", lambda: client.interactions.create(model="gemini-3.8-flash", input="hi")),
]:
    stamps.clear()
    try:
        call()
    except Exception as e:
        print(f"{name}: {len(stamps)} requests, gaps {gaps()} s, {type(e).__name__}")
$ python repro.py
models.generate_content: 4 requests, gaps [1.0, 2.0, 4.0] s, ServerError
interactions.create: 4 requests, gaps [0.5, 1.0, 2.0] s, InternalServerError

HttpRetryOptions documents initial_delay as "If not specified, default to 1.0 second" and max_delay as "default to 60.0 seconds" (types.py:2671-2678). The comment above _DEFAULT_INITIAL_INTERVAL_MS in _gaos/google_genai.py calls 0.5 s and 8 s the default, so one of the two contracts is wrong. An unset jitter differs too: Interactions takes up to 25% off each delay, while client.models adds up to 1 s. #3263 already moved the unset attempts onto _api_client._RETRY_ATTEMPTS. I checked the sync client only.

I'd take all three from _api_client (_RETRY_INITIAL_DELAY, _RETRY_MAX_DELAY, _RETRY_JITTER) in the same way. Or are 0.5 s and 8 s meant to stay specific to Interactions?

Activity

  1. added
    priority: p2Moderately-important priority. Fix may not be included in next release.
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    on Nov 9, 2026
  2. Venkaiahbabuneelam commented on Nov 9, 2026

    @Venkaiahbabuneelam

    Hi @chrikrah,

    The interactions client currently applies its own internal defaults (_DEFAULT_INITIAL_INTERVAL_MS) rather than falling back to the standard _api_client defaults (_RETRY_INITIAL_DELAY and _RETRY_MAX_DELAY) when initial_delay and max_delay are omitted in HttpRetryOptions.

    As a workaround to ensure identical backoff behavior across both endpoints in the interim, explicitly pass initial_delay and max_delay in HttpRetryOptions:

    retry = types.HttpRetryOptions(
        attempts=4,
        initial_delay=1.0,
        max_delay=60.0,
        jitter=0.0,
    )

    Having HttpRetryOptions share consistent defaults across modules is the intended behavior.

    Thanks

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

Metadata

Metadata

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.status:awaiting user responsetype: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions