NousResearch/hermes-agent · warning · TimeoutError
video job {getattr(video, 'id', '?')} did not reach a termin
Error message
video job {getattr(video, 'id', '?')} did not reach a terminal status within {int(self._poll_deadline_s)}s (last status={getattr(video, 'status', None)!r}) What it means
TimeoutError from the bounded polling loop in agent/video_gen_provider.py:440. This replaces client.videos.create_and_poll (which looped at 1/s forever) with a coarse _poll_interval_s sleep and a wall-clock deadline of _poll_deadline_s; if the job's status never enters the terminal set (completed/succeeded/failed/error/cancelled/canceled) before the deadline, this error names the job id and last observed status.
Source
Thrown at agent/video_gen_provider.py:440
def is_available(self) -> bool:
return bool(self._api_key())
def _create_and_poll(self, client: Any, call_kwargs: Dict[str, Any]) -> Any:
"""Create the video job and poll to completion with a hard deadline.
Replaces ``client.videos.create_and_poll`` (unbounded 1/s loop) with a
coarse interval and a wall-clock cap. Returns the terminal video object
(any status); raises :class:`TimeoutError` if the deadline passes
first.
"""
import time
video = client.videos.create(**call_kwargs)
terminal = {"completed", "succeeded", "failed", "error", "cancelled", "canceled"}
deadline = time.monotonic() + self._poll_deadline_s
while getattr(video, "status", None) not in terminal:
if time.monotonic() >= deadline:
raise TimeoutError(
f"video job {getattr(video, 'id', '?')} did not reach a terminal "
f"status within {int(self._poll_deadline_s)}s "
f"(last status={getattr(video, 'status', None)!r})"
)
time.sleep(self._poll_interval_s)
video = client.videos.retrieve(video.id)
return video
def _base_url(self) -> str:
import os
override = os.environ.get(f"{self.name.upper()}_BASE_URL", "").strip()
return override or self._default_base_url
def generate(
self,
prompt: str,
*,View on GitHub (pinned to c896c09c42)
Solutions
- Increase the provider's poll deadline (_poll_deadline_s) to cover the worst-case queue time for the requested duration/resolution.
- Check the job id on the provider's dashboard — the error's (last status=...) tells you whether it was queued vs in-progress vs stalled.
- Treat this timeout as 'unknown outcome': the job may still complete and bill; verify on the provider side before regenerating.
- If jobs are systematically slower than the deadline, lower resolution/duration or switch tier rather than perpetually raising the cap.
Example fix
# before provider._poll_deadline_s = 120 # 2 min; long generations time out # after provider._poll_deadline_s = 900 # 15 min, matches provider's long-queue worst case
Defensive patterns
Strategy: retry
Validate before calling
def deadline_fits_request(poll_deadline_s: int, duration_s: int, tier_queue_s: int) -> bool:
# heuristic: queue + generation should fit inside the deadline
return poll_deadline_s > tier_queue_s + duration_s * 2 Try / catch
try:
video = provider.generate_and_poll(**kwargs)
except TimeoutError as exc:
# outcome unknown — the job may still complete and bill
log.warning("poll deadline hit: %s; checking provider state", exc)
raise PendingJobUnknown(str(exc)) from exc Prevention
- Set _poll_deadline_s above the provider's worst-case queue+generation time for your tier.
- On timeout, check the job id on the provider before regenerating (double billing).
- Keep the coarse poll interval — the wall-clock cap, not the interval, is the safety control.
When it happens
Trigger: A video generation queued long on the provider (busy queue, long duration/high resolution request) so it stays 'queued'/'in_progress' past the deadline; provider API degradation where status updates stall; deadline configured too low for the requested output.
Common situations: Default poll deadline tuned for short clips but the user requested a long high-res generation; provider incident with stuck jobs; slow-tier/free-tier queues with multi-minute waits.
Related errors
- Provider has been unresponsive (no response received) for {_
- Video at {url} was empty (0 bytes).
- OAuth authorization failed
- Provider '{_explicit}' is set in config.yaml but no API key
- No LLM provider configured. Run `hermes model` to select a p
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/2408c58e7bcb298d.
Report an issue: GitHub.