calesthio/OpenMontage · warning · ComfyUIError

Prompt {prompt_id} did not complete within {timeout}s. The j

Error message

Prompt {prompt_id} did not complete within {timeout}s. The job is very likely still running on the ComfyUI server (local/custom workflows on modest GPUs routinely exceed the client wait) — it was not cancelled. Poll GET {{server_url}}/history/{prompt_id} directly, or call generate()/execute() again with a longer timeout and this prompt_id to resume waiting without resubmitting.

What it means

ComfyUIError raised by poll() when the prompt has not produced a completed history entry within the client-side timeout (default 600s, 5s interval). Crucially the job is NOT cancelled server-side — ComfyUI keeps executing; the error message carries prompt_id so you can resume waiting via generate()/execute() with the same prompt_id instead of resubmitting (and paying GPU time again). This is a client patience limit, not a server failure.

Source

Thrown at tools/_comfyui/client.py:213

        if not prompt_id:
            raise ComfyUIError(f"No prompt_id in response: {data}")
        return prompt_id

    def poll(
        self,
        prompt_id: str,
        *,
        timeout: int = 600,
        interval: int = 5,
    ) -> dict:
        """Block until *prompt_id* finishes.  Returns the history entry."""
        deadline = time.time() + timeout
        while time.time() < deadline:
            entry = self._history_entry(prompt_id)
            if entry is not None:
                return entry
            time.sleep(interval)
        raise ComfyUIError(
            f"Prompt {prompt_id} did not complete within {timeout}s. "
            f"The job is very likely still running on the ComfyUI server "
            f"(local/custom workflows on modest GPUs routinely exceed the "
            f"client wait) — it was not cancelled. Poll "
            f"GET {{server_url}}/history/{prompt_id} directly, or call "
            f"generate()/execute() again with a longer timeout and this "
            f"prompt_id to resume waiting without resubmitting.",
            prompt_id=prompt_id,
        )

    def _history_entry(self, prompt_id: str) -> dict | None:
        """Return a completed history entry, or ``None`` while it is absent."""
        resp = requests.get(f"{self.server_url}/history/{prompt_id}", timeout=10)
        resp.raise_for_status()
        entry = resp.json().get(prompt_id)
        if entry is None:
            return None
        status = entry.get("status", {})

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Retry the call with the SAME prompt_id and a longer timeout — the job continues server-side (e.g. timeout=3600)
  2. Poll GET {server_url}/history/{prompt_id} directly to watch progress without the client
  3. Pre-warm models (run a tiny job first) and keep queues empty before long generations
  4. Raise the timeout argument up front for known-heavy workflows instead of relying on the 600s default

Example fix

# before
entry = client.poll(prompt_id)  # default timeout=600

# after
entry = client.poll(prompt_id, timeout=3600, interval=10)
Defensive patterns

Strategy: retry

Validate before calling

import requests
def queue_depth(server_url: str) -> int:
    q = requests.get(f"{server_url}/queue", timeout=5).json()
    return len(q.get("queue_running", [])) + len(q.get("queue_pending", []))
if queue_depth(server_url) > 2:
    print("warning: ComfyUI queue is deep; long waits likely")

Try / catch

def poll_with_resume(client, prompt_id, timeouts=(600, 1800, 7200)):
    for t in timeouts:
        try:
            return client.poll(prompt_id, timeout=t)
        except ComfyUIError as e:
            if "did not complete within" not in str(e):
                raise
    raise RuntimeError("job never completed; inspect server manually")

Prevention

When it happens

Trigger: Polling a heavy local workflow (SDXL/high-res video, custom multi-stage graphs) on a modest GPU where 600s isn't enough; queue congestion because other jobs are ahead; long model-load times on first run when weights download or swap from disk.

Common situations: Default 600s timeout used for video-generation workflows that take 20-40 min; ComfyUI on a shared box with a deep queue; cold start downloading a 6GB checkpoint inside the job.

Understand the failure class

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/1a96c9fe670e7f03. Report an issue: GitHub.