{"record":{"id":"cad0499e9e0351b0","repo":"calesthio/OpenMontage","slug":"no-history-entry-for-prompt-id-after-completion","errorCode":null,"errorMessage":"No history entry for {prompt_id} after completion","messagePattern":"No history entry for (.+?) after completion","errorType":"exception","errorClass":"ComfyUIError","httpStatus":null,"severity":"warning","filePath":"tools/_comfyui/client.py","lineNumber":337,"sourceCode":"                    finished = True\n                    break\n        finally:\n            conn.close()\n\n        if not finished:\n            entry = self._history_entry_if_reachable(prompt_id)\n            if entry is not None:\n                return entry\n            raise ComfyUIError(\n                f\"Prompt {prompt_id} did not complete within {timeout}s \"\n                f\"(websocket wait). The job was not cancelled — resume with \"\n                f\"resume_prompt_id={prompt_id!r} and a longer timeout.\",\n                prompt_id=prompt_id,\n            )\n\n        entry = self._history_entry(prompt_id)\n        if entry is None:\n            raise ComfyUIError(\n                f\"No history entry for {prompt_id} after completion\",\n                prompt_id=prompt_id,\n            )\n        return entry\n\n    def _wait(\n        self,\n        prompt_id: str,\n        *,\n        timeout: int,\n        interval: int,\n        on_progress: Callable[[dict], None] | None = None,\n    ) -> dict:\n        \"\"\"Wait for *prompt_id*, preferring the websocket feed over polling.\n\n        Falls back to :meth:`poll` when ``websocket-client`` isn't installed\n        or the websocket can't be established/maintained. A genuine\n        :class:`ComfyUIError` (execution error or deadline reached) is never","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/_comfyui/client.py#L319-L355","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Retry the history GET once after a short delay — eventual consistency often resolves it","If outputs matter, check the server's output/ directory directly — finished artifacts are usually on disk even when history is missing","Pin clients to a single ComfyUI worker (no LB round-robin) or enable shared history storage","For one-off recovery, list GET /history and search for the prompt_id (it may exist under a slightly different state)"],"exampleFix":"# before\nentry = client.wait_ws(prompt_id, timeout=600)  # raises if history vanished\n\n# after\nentry = client.wait_ws(prompt_id, timeout=600)\n# fallback: artifacts are typically in ComfyUI output/ even without history\n# ls <comfyui_dir>/output/ and match by timestamp","handlingStrategy":"retry","validationCode":"import requests\ndef history_has(server_url: str, prompt_id: str) -> bool:\n    try:\n        return prompt_id in requests.get(f\"{server_url}/history\", timeout=5).json()\n    except requests.RequestException:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    entry = client.wait_ws(prompt_id, timeout=timeout)\nexcept ComfyUIError as e:\n    if \"No history entry\" in str(e):\n        import time\n        time.sleep(5)\n        # artifacts may still exist on disk in ComfyUI output/\n        if history_has(server_url, prompt_id):\n            entry = client._history_entry(prompt_id)\n        else:\n            raise","preventionTips":["Pin each client to one ComfyUI worker (no LB round-robin) — history is per-process","Treat finished-artifact-on-disk as a valid fallback when history is pruned","Retry the history GET once after a short delay before failing"],"tags":["comfyui","history","consistency","rare"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}