{"record":{"id":"921ad04550062f4a","repo":"harry0703/MoneyPrinterTurbo","slug":"sonilo-returned-no-audio-data","errorCode":null,"errorMessage":"Sonilo returned no audio data","messagePattern":"Sonilo returned no audio data","errorType":"exception","errorClass":"SoniloError","httpStatus":null,"severity":"error","filePath":"app/services/sonilo.py","lineNumber":267,"sourceCode":"            if not isinstance(encoded_chunk, str) or not encoded_chunk:\n                raise SoniloError(\"Sonilo returned an empty audio chunk\")\n            try:\n                chunk = base64.b64decode(encoded_chunk, validate=True)\n            except (binascii.Error, ValueError) as exc:\n                raise SoniloError(\"Sonilo returned an invalid audio chunk\") from exc\n            if not chunk:\n                raise SoniloError(\"Sonilo returned an empty audio chunk\")\n            total_bytes += len(chunk)\n            if total_bytes > MAX_GENERATED_AUDIO_BYTES:\n                raise SoniloError(\"Sonilo audio exceeds the 30 MB limit\")\n            output.write(chunk)\n        output.flush()\n        os.fsync(output.fileno())\n\n    if not completed:\n        raise SoniloError(\"Sonilo stream ended before completion\")\n    if total_bytes <= 0:\n        raise SoniloError(\"Sonilo returned no audio data\")\n    return total_bytes, title\n\n\ndef _request_bgm(video_path: str, output_path: str, prompt: str) -> str:\n    \"\"\"请求配乐并在完整协议及音频校验通过后原子保存。\"\"\"\n    output_dir = os.path.dirname(os.path.abspath(output_path))\n    os.makedirs(output_dir, exist_ok=True)\n    descriptor, temp_audio_path = tempfile.mkstemp(\n        prefix=\".sonilo-audio-\",\n        suffix=Path(output_path).suffix or \".m4a\",\n        dir=output_dir,\n    )\n    os.close(descriptor)\n    try:\n        logger.info(\n            f\"requesting Sonilo background music: video={video_path}, \"\n            f\"prompt_provided={bool(prompt)}\"\n        )","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/harry0703/MoneyPrinterTurbo/blob/1f9f19c2021a68d04df228f33e9099a0c947f6f8/app/services/sonilo.py#L249-L285","documentation":"Raised when the stream ended cleanly (a complete event was received) but zero audio bytes were accumulated. The protocol was honored yet the provider delivered a finished, empty result. It is separated from error 93 to distinguish a truncated stream from a legitimate-but-empty generation, typically a server-side failure that still emits complete.","triggerScenarios":"The provider emits a complete event immediately (or after only title or meta events) because generation failed silently, the video was rejected after upload, or credits were exhausted without an error event; a server bug produces a zero-length result.","commonSituations":"Provider incidents where failures bypass the error channel; unsupported video content accepted at upload then skipped server-side; quota exhausted mid-request with a graceful-complete bug.","solutions":["Retry the task once; an empty-but-complete result is frequently a transient provider fault.","Check account credits and usage on the Sonilo dashboard for evidence the generation ever ran.","Try a different source video or prompt to rule out content-triggered silent rejection.","If reproducible, report to Sonilo support: complete with zero audio_chunk events violates their own protocol."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    audio = request_bgm(video, out, prompt)\nexcept SoniloError as exc:\n    if \"returned no audio data\" in str(exc):\n        # complete-but-empty is usually a silent provider failure: retry once\n        retry_once()\n    raise","preventionTips":["Treat complete-with-zero-audio as a provider health signal; count occurrences and alert past a threshold.","Never promote the empty temp file to the output path; the library already prevents this, keep callers from bypassing it."],"tags":["sonilo","provider-error","streaming","audio"],"backgroundTag":null,"analyzedSha":"1f9f19c2021a68d04df228f33e9099a0c947f6f8","analyzedAt":"2026-08-14T19:41:05.568Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}