NousResearch/hermes-agent · error · TimeoutError

Non-streaming API call timed out after {int(time.time() - ca

Error message

Non-streaming API call timed out after {int(time.time() - call_start)}s with no response (threshold: {int(stale_timeout)}s)

What it means

The non-streaming API call raised a transport exception and the watchdog had already flagged the request stale; Hermes deliberately converts this into a retryable TimeoutError (never InterruptedError, which would read as 'user wants to stop') so the outer retry loop reconnects on a fresh pool. Elapsed time and threshold are included for diagnosis.

Source

Thrown at agent/chat_completion_helpers.py:814

    # Only a clean return may report the reuse reason (request_complete):
    # after an error or interrupt the wire client is really closed so the
    # retry builds a fresh pool (see _REQUEST_CLIENT_REUSE_REASONS).
    succeeded = False
    try:
        response = _dispatch_nonstreaming_api_request(
            agent, api_kwargs, make_client=_make_client
        )
    except Exception:
        if getattr(agent, "_interrupt_requested", False):
            raise InterruptedError("Agent interrupted during API call") from None
        with request_client_lock:
            was_stale = request_state["stale"]
        if was_stale:
            # The transport error is the expected consequence of our own
            # abort. Raise a retryable TimeoutError (never InterruptedError,
            # which the outer loop treats as "the user wants to stop") so the
            # retry loop reconnects on a fresh pool.
            raise TimeoutError(
                f"Non-streaming API call timed out after "
                f"{int(time.time() - call_start)}s with no response "
                f"(threshold: {int(stale_timeout)}s)"
            ) from None
        raise
    else:
        if getattr(agent, "_interrupt_requested", False):
            raise InterruptedError("Agent interrupted during API call")
        # Close the race window against a timer firing between response
        # arrival and this unwind: marking ``done`` under the lock makes any
        # later timer callback a no-op, so the reset below cannot be
        # overwritten by a stray bump after a successful call. A timer that
        # already won the lock left ``stale`` set — the request still
        # completed, so return the response (the streak reset undoes the
        # bump; the poisoned client is discarded by the finally).
        with request_client_lock:
            request_state["done"] = True
        _reset_stale_streak(agent)

View on GitHub (pinned to c896c09c42)

Solutions

  1. Retry — this error is intentionally retryable and the loop uses a fresh connection pool.
  2. If recurrent, lower prompt size or switch to a streaming call (time-to-first-token arrives earlier).
  3. Increase the stale timeout for legitimately slow setups (very large contexts, local models on weak hardware).
  4. Check provider status / network path if every call times out.
Defensive patterns

Strategy: retry

Validate before calling

if estimated_time_to_first_byte(provider, prompt_tokens) > stale_timeout:
    trim_prompt_or_switch_to_streaming()

Try / catch

attempts = 0
while attempts < 3:
    try:
        return non_streaming_call(...)
    except TimeoutError as e:
        if "no response" in str(e) and "threshold" in str(e):
            attempts += 1
            backoff(attempts)
            continue
        raise

Prevention

When it happens

Trigger: A non-streaming completion received no response within stale_timeout; the abort timer fired, killed the request, the transport then raised, and the stale flag was set at agent/chat_completion_helpers.py:814.

Common situations: Slow provider exceeding the stale threshold; oversized prompt causing long time-to-first-byte on non-streaming responses; network black-holing; provider under heavy load.

Understand the failure class

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/94309853ae0ba06e. Report an issue: GitHub.