hermes - 💡(How to fix) Fix [Enhancement] Empty response retries have no backoff delay — immediate retry wastes API calls

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

Compare with API error retries (line ~1512, ~3347): Add time.sleep(jittered_backoff(...)) (or configurable delays) to the empty-response retry path, consistent with the existing API error retry mechanism.

Root Cause

  • #7069 — Infinite retry loop caused by stream stale timeout (also "immediate retry" pattern, different trigger)
    • #7968 — Empty response retry bypassed by _last_content_with_tools fallback

Fix Action

Fix / Workaround

Current Workaround

Patch conversation_loop.py to add escalating time.sleep():

_empty_backoff_delays = [60, 120, 300]
_delay = _empty_backoff_delays[min(retry_attempt - 1, len(_empty_backoff_delays) - 1)]
time.sleep(_delay)

Code Example

# Current code — no delay between retries
  if _truly_empty and ... and agent._empty_content_retries < 3:
      agent._empty_content_retries += 1
      logger.warning("Empty response — retry %d/3", ...)
      agent._buffer_status(f"⚠️ Empty response — retrying ({retries}/3)")
      continue   # ← immediate, no sleep

---

wait_time = jittered_backoff(retry_count, base_delay=5.0, max_delay=120.0)
  time.sleep(wait_time)

---

_empty_backoff_delays = [60, 120, 300]
  _delay = _empty_backoff_delays[min(retry_attempt - 1, len(_empty_backoff_delays) - 1)]
  time.sleep(_delay)

---

agent:
    empty_retry_backoff: [60, 120, 300]  # seconds per attempt
RAW_BUFFERClick to expand / collapse

title: "[Enhancement] Empty response retries have no backoff delay — immediate retry wastes API calls"

body: |

Bug/Enhancement Description

When the model returns an empty response (no content, no reasoning), the agent retries up to 3 times with zero delay before falling back to the next provider. All 3 retries fire back-to-back within seconds.

This is inconsistent with the existing jittered_backoff() mechanism used for API-level errors (rate limits, timeouts, 5xx), which properly waits between attempts. The empty-response path uses a bare continue with no time.sleep().

Location in source

File: agent/conversation_loop.py (approximately line 4109-4120 in current main)

# Current code — no delay between retries
if _truly_empty and ... and agent._empty_content_retries < 3:
    agent._empty_content_retries += 1
    logger.warning("Empty response — retry %d/3", ...)
    agent._buffer_status(f"⚠️ Empty response — retrying ({retries}/3)")
    continue   # ← immediate, no sleep

Compare with API error retries (line ~1512, ~3347):

wait_time = jittered_backoff(retry_count, base_delay=5.0, max_delay=120.0)
time.sleep(wait_time)

Impact

  1. Wasted API calls — 3 retries fire in <1 second. If the model is temporarily degraded, all 3 are wasted.
  2. Worst case: 6 rapid-fire calls — 3 on primary model + 3 on fallback = 6 consecutive zero-delay API calls.
  3. User confusion — The status message retrying (3/3) appears and vanishes so fast the user never sees it.

Current Workaround

Patch conversation_loop.py to add escalating time.sleep():

_empty_backoff_delays = [60, 120, 300]
_delay = _empty_backoff_delays[min(retry_attempt - 1, len(_empty_backoff_delays) - 1)]
time.sleep(_delay)

Proposed Fix

Add time.sleep(jittered_backoff(...)) (or configurable delays) to the empty-response retry path, consistent with the existing API error retry mechanism.

Optionally make the backoff delays configurable via config.yaml under the agent: section, e.g.:

agent:
  empty_retry_backoff: [60, 120, 300]  # seconds per attempt

Environment

  • Hermes Agent version: latest main (commit 860cf28)
  • Python: 3.11
  • Model: glm-5.1 / glm-4.7 (zai provider)
  • Provider: OpenAI-compatible API

Related Issues

  • #7069 — Infinite retry loop caused by stream stale timeout (also "immediate retry" pattern, different trigger)
  • #7968 — Empty response retry bypassed by _last_content_with_tools fallback

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [Enhancement] Empty response retries have no backoff delay — immediate retry wastes API calls