harry0703/MoneyPrinterTurbo · error · SoniloError

Sonilo returned an invalid audio chunk

Error message

Sonilo returned an invalid audio chunk

What it means

Raised when the base64 payload of an audio chunk fails strict decoding (base64.b64decode with validate=True raises binascii.Error or ValueError). The chunk field was a non-empty string but contains characters outside the base64 alphabet or wrong padding; the data is corrupted or not actually standard base64.

Source

Thrown at app/services/sonilo.py:254

                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


def _request_bgm(video_path: str, output_path: str, prompt: str) -> str:
    """请求配乐并在完整协议及音频校验通过后原子保存。"""

View on GitHub (pinned to 1f9f19c202)

Solutions

  1. Capture the first failing chunk string and test the URL-safe alphabet (altchars) — if that decodes, add URL-safe handling.
  2. Check for transport mangling: compare the chunk length modulo 4 (padding loss) and inspect for injected CRLF sequences.
  3. Review the provider changelog for encoding changes.
  4. If the corruption is network truncation, retry the request.

Example fix

# before
chunk = base64.b64decode(encoded_chunk, validate=True)
# after (accept URL-safe alphabet too)
chunk = base64.b64decode(encoded_chunk.translate(str.maketrans('-_', '+/')), validate=True)
Defensive patterns

Strategy: retry

Validate before calling

import base64, binascii

def is_std_base64(s: str) -> bool:
    try:
        base64.b64decode(s, validate=True)
        return True
    except (binascii.Error, ValueError):
        return False

Try / catch

try:
    audio = request_bgm(video, out, prompt)
except SoniloError as exc:
    if "invalid audio chunk" in str(exc):
        # encoding drift vs corruption: retry once, then report
        retry_once_or_report_encoding_issue(exc)
    raise

Prevention

When it happens

Trigger: The chunk arrives as URL-safe base64 (dash and underscore instead of plus and slash) while the decoder expects the standard alphabet; padding was stripped by a transport layer; mojibake from a mis-declared charset; the provider switched to base85 or hex encoding.

Common situations: Provider changes base64 flavor between API versions; a gateway or middleware re-encodes or mangles the body; proxies applying charset transcoding to the streaming response.

Related errors


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