{"record":{"id":"0ff706f6e92a1938","repo":"Comfy-Org/ComfyUI","slug":"sonilo-api-returned-no-audio-data","errorCode":null,"errorMessage":"Sonilo API returned no audio data.","messagePattern":"Sonilo API returned no audio data\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/nodes_sonilo.py","lineNumber":251,"sourceCode":"                        audio_streams[stream_idx] = []\n                    audio_streams[stream_idx].append(chunk_data)\n\n                    now = time.monotonic()\n                    if now - last_chunk_status_ts >= 1.0:\n                        total_chunks = sum(len(chunks) for chunks in audio_streams.values())\n                        elapsed = int(now - start_ts)\n                        status_lines = [\"Status: Receiving audio\"]\n                        if title:\n                            status_lines.append(f\"Title: {title}\")\n                        status_lines.append(f\"Chunks received: {total_chunks}\")\n                        status_lines.append(f\"Time elapsed: {elapsed}s\")\n                        PromptServer.instance.send_progress_text(\"\\n\".join(status_lines), node_id)\n                        last_chunk_status_ts = now\n                elif evt_type == \"complete\":\n                    break\n\n    if not audio_streams:\n        raise Exception(\"Sonilo API returned no audio data.\")\n\n    PromptServer.instance.send_progress_text(\"Status: Completed\", node_id)\n    selected_stream = 0 if 0 in audio_streams else min(audio_streams)\n    return b\"\".join(audio_streams[selected_stream])\n\n\nasync def _extract_error_message(resp: aiohttp.ClientResponse) -> str:\n    \"\"\"Extract a human-readable error message from an HTTP error response.\"\"\"\n    try:\n        error_body = await resp.json()\n        detail = error_body.get(\"detail\", {})\n        if isinstance(detail, dict):\n            return detail.get(\"message\", str(detail))\n        return str(detail)\n    except Exception:\n        return await resp.text()\n\n","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_sonilo.py#L233-L269","documentation":"Raised after the Sonilo streaming loop finishes (complete event or stream end) if no audio chunks were collected in any stream. The request technically succeeded but produced zero usable audio bytes, so joining/returning audio is impossible. It is the final guard before selecting a stream and returning bytes.","triggerScenarios":"Stream completes without any audio chunk events — server closed early, only status/metadata events arrived, or all chunk events carried empty payloads so audio_streams stayed empty.","commonSituations":"Server-side truncation after moderation passed; network proxy cutting the stream body; Sonilo API changes emitting chunks under a different event type that the node ignores.","solutions":["Retry the generation — truncated streams are often transient","Check network/proxy settings for buffering or early termination of streaming responses","If persistent, inspect the raw NDJSON traffic to see whether audio events use a changed schema"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in range(2):\n    try:\n        return await _sonilo_generate(url, form, headers)\n    except Exception as e:\n        if \"no audio data\" in str(e) and attempt == 0:\n            continue\n        raise","preventionTips":["Retry once on empty streams — truncation is often transient","Avoid intermediaries that buffer streaming responses (some proxies do)","Log received event types when debugging to detect schema drift"],"tags":["sonilo","streaming","empty-response","audio"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}