harry0703/MoneyPrinterTurbo · error · SoniloError
Sonilo generation failed: {message}
Error message
Sonilo generation failed: {message} What it means
Raised when the Sonilo stream itself reports failure: an event with type 'error' arrives, and the message is taken from its 'message' or 'error' field (falling back to unknown error). This is the provider's own error channel (content-policy rejections, prompt problems, server-side generation failures) surfaced verbatim in the raised SoniloError.
Source
Thrown at app/services/sonilo.py:234
把第一条配乐流按事件顺序写入临时文件,并限制最大体积。
API 可能同时返回多条候选流;当前产品只需要一条 BGM,所以固定选择
stream_index=0。只有收到 complete 事件并通过 FFmpeg 完整解码后才会发布。
"""
total_bytes = 0
title = ""
completed = False
with open(temp_audio_path, "wb") as output:
for raw_line in response.iter_lines():
if not raw_line:
continue
event = _parse_event(raw_line)
event_type = event["type"]
if event_type == "error":
message = str(
event.get("message") or event.get("error") or "unknown error"
)
raise SoniloError(f"Sonilo generation failed: {message}")
if event_type == "title":
title = str(event.get("title") or event.get("data") or "")[:200]
continue
if event_type == "complete":
completed = True
break
if event_type != "audio_chunk":
logger.debug(f"ignoring unsupported Sonilo event: type={event_type}")
continue
stream_index = event.get("stream_index", 0)
if stream_index != 0:
continue
encoded_chunk = event.get("data") or event.get("audio")
if not isinstance(encoded_chunk, str) or not encoded_chunk:
raise SoniloError("Sonilo returned an empty audio chunk")
try:
chunk = base64.b64decode(encoded_chunk, validate=True)View on GitHub (pinned to 1f9f19c202)
Solutions
- Read the embedded message; it is the provider's reason and dictates the fix (policy vs capacity vs credits).
- For content-policy messages, rephrase the prompt and/or change the video; retrying unchanged will fail again.
- For credit or quota messages, top up or switch the API key, then retry.
- For transient provider failures, retry the task after a short delay.
Defensive patterns
Strategy: try-catch
Validate before calling
# keep prompts inside policy before submitting
if len(prompt) > sonilo.MAX_PROMPT_LENGTH:
prompt = prompt[: sonilo.MAX_PROMPT_LENGTH] Try / catch
try:
audio = request_bgm(video, out, prompt)
except SoniloError as exc:
msg = str(exc)
if msg.startswith("Sonilo generation failed:"):
reason = msg.split(":", 1)[1]
if is_content_policy(reason):
fail_task_with_user_visible_reason(reason) # do NOT retry
else:
schedule_retry_once()
raise Prevention
- Surface the provider message to the end user; it names the policy or quota cause and prevents pointless retries.
- Sanitize and length-cap prompts client-side and avoid copyrighted or artist names in prompts.
When it happens
Trigger: POST /v1/video-to-music completes the HTTP handshake with 2xx but the generation later fails server-side and the stream emits an error event. Typical embedded messages: content-policy rejection of the video or prompt, internal generation failure, credit exhaustion mid-generation.
Common situations: Prompt text (up to 2000 chars) trips content moderation; the source video contains flagged content; provider capacity issues abort generation; the account runs out of credits after the request started.
Related errors
- Sonilo returned no audio data
- Sonilo returned malformed streaming data
- Sonilo returned an invalid streaming event
- Sonilo returned an empty audio chunk
- Sonilo returned an invalid audio chunk
AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14).
Data as JSON: /api/errors/f687a03082194891.
Report an issue: GitHub.