calesthio/OpenMontage · warning · ComfyUIError

No history entry for {prompt_id} after completion

Error message

No history entry for {prompt_id} after completion

What it means

ComfyUIError raised by wait_ws in the narrow case where the websocket DID deliver the completion frame ('executing' with node=None) but a subsequent history fetch for that prompt_id returned no entry. Normally completion implies a history entry exists; its absence means the history view is inconsistent — ComfyUI restarted and lost in-memory history, history was pruned, or a multi-worker setup routed the history request to a different worker.

Source

Thrown at tools/_comfyui/client.py:337

                    finished = True
                    break
        finally:
            conn.close()

        if not finished:
            entry = self._history_entry_if_reachable(prompt_id)
            if entry is not None:
                return entry
            raise ComfyUIError(
                f"Prompt {prompt_id} did not complete within {timeout}s "
                f"(websocket wait). The job was not cancelled — resume with "
                f"resume_prompt_id={prompt_id!r} and a longer timeout.",
                prompt_id=prompt_id,
            )

        entry = self._history_entry(prompt_id)
        if entry is None:
            raise ComfyUIError(
                f"No history entry for {prompt_id} after completion",
                prompt_id=prompt_id,
            )
        return entry

    def _wait(
        self,
        prompt_id: str,
        *,
        timeout: int,
        interval: int,
        on_progress: Callable[[dict], None] | None = None,
    ) -> dict:
        """Wait for *prompt_id*, preferring the websocket feed over polling.

        Falls back to :meth:`poll` when ``websocket-client`` isn't installed
        or the websocket can't be established/maintained. A genuine
        :class:`ComfyUIError` (execution error or deadline reached) is never

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Retry the history GET once after a short delay — eventual consistency often resolves it
  2. If outputs matter, check the server's output/ directory directly — finished artifacts are usually on disk even when history is missing
  3. Pin clients to a single ComfyUI worker (no LB round-robin) or enable shared history storage
  4. For one-off recovery, list GET /history and search for the prompt_id (it may exist under a slightly different state)

Example fix

# before
entry = client.wait_ws(prompt_id, timeout=600)  # raises if history vanished

# after
entry = client.wait_ws(prompt_id, timeout=600)
# fallback: artifacts are typically in ComfyUI output/ even without history
# ls <comfyui_dir>/output/ and match by timestamp
Defensive patterns

Strategy: retry

Validate before calling

import requests
def history_has(server_url: str, prompt_id: str) -> bool:
    try:
        return prompt_id in requests.get(f"{server_url}/history", timeout=5).json()
    except requests.RequestException:
        return False

Try / catch

try:
    entry = client.wait_ws(prompt_id, timeout=timeout)
except ComfyUIError as e:
    if "No history entry" in str(e):
        import time
        time.sleep(5)
        # artifacts may still exist on disk in ComfyUI output/
        if history_has(server_url, prompt_id):
            entry = client._history_entry(prompt_id)
        else:
            raise

Prevention

When it happens

Trigger: wait_ws() finishes cleanly, then _history_entry(prompt_id) returns None: ComfyUI restarted between execution and the history GET; history retention cleared; a load balancer in front of multiple ComfyUI workers without shared state.

Common situations: Server crash/restart right at job end; ComfyUI's history cap pruning old entries when many jobs ran concurrently; distributed ComfyUI fronted by one URL.

Related errors


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