{"record":{"id":"270e3a4319c5f1db","repo":"ATH-MaaS/Pixelle-Video","slug":"image-analysis-failed-error-msg","errorCode":null,"errorMessage":"Image analysis failed: {error_msg}","messagePattern":"Image analysis failed: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"pixelle_video/services/image_analysis.py","lineNumber":155,"sourceCode":"            kit = await self.core._get_or_create_comfykit()\n            \n            # Determine what to pass to ComfyKit based on source\n            if workflow_info[\"source\"] == \"runninghub\" and \"workflow_id\" in workflow_info:\n                # RunningHub: pass workflow_id\n                workflow_input = workflow_info[\"workflow_id\"]\n                logger.info(f\"Executing RunningHub workflow: {workflow_input}\")\n            else:\n                # Selfhost: pass file path\n                workflow_input = workflow_info[\"path\"]\n                logger.info(f\"Executing selfhost workflow: {workflow_input}\")\n            \n            result = await kit.execute(workflow_input, workflow_params)\n            \n            # 5. Extract description from result\n            if result.status != \"completed\":\n                error_msg = result.msg or \"Unknown error\"\n                logger.error(f\"Image analysis failed: {error_msg}\")\n                raise Exception(f\"Image analysis failed: {error_msg}\")\n            \n            # Extract text description from result (format varies by source)\n            description = None\n            \n            # Try format 1: Selfhost outputs (direct text in outputs)\n            # Format: {'6': {'text': ['description text']}}\n            if result.outputs:\n                for node_id, node_output in result.outputs.items():\n                    if 'text' in node_output:\n                        text_list = node_output['text']\n                        if text_list and len(text_list) > 0:\n                            description = text_list[0]\n                            break\n            \n            # Try format 2: RunningHub raw_data (text file URL)\n            # Format: {'raw_data': [{'fileUrl': 'https://...txt', 'fileType': 'txt', ...}]}\n            if not description and result.outputs and 'raw_data' in result.outputs:\n                raw_data = result.outputs['raw_data']","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/pixelle_video/services/image_analysis.py#L137-L173","documentation":"After the analysis workflow executes via kit.execute(), the service checks result.status and raises a generic Exception if it is not \"completed\". The workflow runner (ComfyUI selfhost or RunningHub) reported a failure, and the underlying result.msg (e.g. node error, OOM, timeout) is embedded in the message.","triggerScenarios":"kit.execute(workflow_input, workflow_params) returns a result whose status is \"failed\"/\"error\" — the remote ComfyUI workflow errored on a node, the RunningHub workflow_id run failed, prompts failed validation, or the execution timed out.","commonSituations":"ComfyUI server overloaded or GPU OOM; workflow file incompatible with installed custom nodes; invalid RunningHub workflow_id or API credit exhaustion; model checkpoint referenced by the workflow missing on the server.","solutions":["Read the embedded error_msg in the exception to identify which workflow node failed","Check the ComfyUI/RunningHub server logs for the actual node error (missing model, OOM, bad node)","Verify the workflow (resolve_workflow_path for the source) is valid for the target backend","Retry once if the failure was transient (server busy/timeout), then fail"],"exampleFix":"try:\n    desc = await analyzer(image_path=img, source=\"selfhost\")\nexcept Exception as e:\n    logger.warning(f\"analysis failed ({e}); retrying once\")\n    desc = await analyzer(image_path=img, source=\"selfhost\")","handlingStrategy":"try-catch","validationCode":"wf = resolve_workflow_path(\"analyse_image\", source)\nif not Path(wf).exists() and source == \"selfhost\":\n    raise FileNotFoundError(f\"workflow missing: {wf}\")","typeGuard":"def workflow_succeeded(result) -> bool:\n    return getattr(result, \"status\", None) == \"completed\" and bool(getattr(result, \"outputs\", None))","tryCatchPattern":"for attempt in range(2):\n    try:\n        return await analyzer(image_path=img, source=src)\n    except Exception as e:\n        if attempt == 1 or \"timeout\" not in str(e).lower():\n            raise\n        await asyncio.sleep(5)","preventionTips":["Check backend server health (ComfyUI queue/GPU memory) before batch runs","Keep workflow JSONs in sync with installed custom nodes on the server","Validate RunningHub workflow_id and API credits before long pipelines","Log result.msg on failure — it names the failing node"],"tags":["python","workflow-execution","comfyui"],"backgroundTag":"workflow-execution-failed","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}