harry0703/MoneyPrinterTurbo · error · SoniloError

Sonilo returned an empty audio chunk

Error message

Sonilo returned an empty audio chunk

What it means

Raised on an audio_chunk event for stream_index 0 whose payload (the 'data' or 'audio' field) is missing, None, or not a non-empty string. Base64-encoded audio is expected; anything else (an empty string, a nested object, differently encoded bytes) aborts the stream write immediately.

Source

Thrown at app/services/sonilo.py:250

                    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)
            except (binascii.Error, ValueError) as exc:
                raise SoniloError("Sonilo returned an invalid audio chunk") from exc
            if not chunk:
                raise SoniloError("Sonilo returned an empty audio chunk")
            total_bytes += len(chunk)
            if total_bytes > MAX_GENERATED_AUDIO_BYTES:
                raise SoniloError("Sonilo audio exceeds the 30 MB limit")
            output.write(chunk)
        output.flush()
        os.fsync(output.fileno())

    if not completed:
        raise SoniloError("Sonilo stream ended before completion")
    if total_bytes <= 0:
        raise SoniloError("Sonilo returned no audio data")
    return total_bytes, title

View on GitHub (pinned to 1f9f19c202)

Solutions

  1. Temporarily log the event keys for failing chunks to see which field carries audio now (data vs audio vs a new name).
  2. If heartbeats: skip zero-payload audio_chunk events instead of failing, but only after confirming with provider docs that they are legal.
  3. If the field was renamed, update the data-or-audio lookup in app/services/sonilo.py:249.
  4. Report persistent empty chunks to Sonilo support with a timestamp and request id.

Example fix

# before
encoded_chunk = event.get("data") or event.get("audio")
# after (tolerate provider heartbeat chunks after confirming legality)
encoded_chunk = event.get("data") or event.get("audio")
if encoded_chunk is None and event.get("heartbeat"):
    continue
Defensive patterns

Strategy: try-catch

Type guard

def has_audio_payload(event: dict) -> bool:
    payload = event.get("data") or event.get("audio")
    return isinstance(payload, str) and len(payload) > 0

Try / catch

try:
    audio = request_bgm(video, out, prompt)
except SoniloError as exc:
    if "empty audio chunk" in str(exc):
        log_stream_context_and_report_to_provider()  # protocol violation upstream
    raise

Prevention

When it happens

Trigger: A stream event of type audio_chunk with stream_index 0 but no data field; data explicitly null; the provider sends raw bytes encoded differently (for example hex) or an empty-string placeholder as keep-alive; a schema change moving audio to a new field name.

Common situations: Provider API revision renaming the audio field; the server sending heartbeat chunk events with no payload; an upstream bug emitting chunks before audio is ready.

Related errors


AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14). Data as JSON: /api/errors/70c7e1df235f889f. Report an issue: GitHub.