NousResearch/hermes-agent · error · TimeoutError

Non-streaming API call timed out before request dispatch (th

Error message

Non-streaming API call timed out before request dispatch (threshold: {int(stale_timeout)}s)

What it means

On the non-streaming API path, a stale watchdog detected that the call exceeded the stale threshold before the request was even dispatched (client registration/creation stalled, e.g. a wedged connection pool). The client was aborted via _abort_request_openai_client and the code raises TimeoutError pre-dispatch so the retry loop can rebuild on a fresh pool instead of stacking onto the dead one.

Source

Thrown at agent/chat_completion_helpers.py:744

                # (registration race): the abort found no sockets to kill, so
                # handing this client to dispatch would open a brand-new
                # socket after the only watchdog already fired. Abort it here
                # and fail the call instead. (The residual window — timer
                # firing between this registration and httpx opening its
                # socket — is accepted: it is ms-scale against a >=90s budget
                # and self-bounds at the OS connect-retry cap.)
                stale_before_dispatch = True
                try:
                    agent._abort_request_openai_client(
                        client, reason="stale_call_kill"
                    )
                except Exception:
                    logger.debug(
                        "Inline abort after late client registration failed",
                        exc_info=True,
                    )
        if stale_before_dispatch:
            raise TimeoutError(
                "Non-streaming API call timed out before request dispatch "
                f"(threshold: {int(stale_timeout)}s)"
            )
        agent._active_request_abort = _abort_active_request
        return client

    def _activity_heartbeat() -> None:
        # Do not put the API call itself on another worker thread — that is
        # the nested-pool deadlock this path exists to avoid (#60203). This
        # ticker only refreshes the activity clock.
        while not activity_hb_stop.wait(_DIRECT_API_ACTIVITY_HEARTBEAT_SECONDS):
            try:
                agent._touch_activity("waiting for non-streaming API response")
            except Exception:
                pass

    activity_hb = threading.Thread(
        target=_activity_heartbeat,

View on GitHub (pinned to c896c09c42)

Solutions

  1. Let the retry loop run — the pre-dispatch abort is designed to reconnect on a fresh pool; persistent recurrence means the endpoint is down.
  2. Verify the base_url endpoint health (curl -m 10).
  3. Restart or switch the model server/provider.
  4. For local endpoints, confirm the server process is alive and not out of file descriptors.
Defensive patterns

Strategy: retry

Validate before calling

import socket, urllib.parse
def endpoint_dispatchable(base_url, timeout=10) -> bool:
    u = urllib.parse.urlparse(base_url)
    try:
        with socket.create_connection((u.hostname, u.port or (443 if u.scheme == "https" else 80)), timeout=timeout):
            return True
    except OSError:
        return False

Try / catch

for attempt in range(max_retries):
    try:
        return non_streaming_call(...)
    except TimeoutError as e:
        if "before request dispatch" in str(e):
            continue  # fresh pool on next iteration by design
        raise

Prevention

When it happens

Trigger: The make_client/registration path itself blocks past the stale_timeout — connect-retry caps, exhausted connection pool, or DNS stall — before any bytes are sent (agent/chat_completion_helpers.py:744).

Common situations: Provider endpoint half-down (TCP accepts, TLS hangs); saturated local connection pool from earlier stale calls; DNS issues; localhost model server that died with sockets lingering.

Understand the failure class

Related errors


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