harry0703/MoneyPrinterTurbo · error · SoniloError

failed to generate Sonilo video proxy: {detail}

Error message

failed to generate Sonilo video proxy: {detail}

What it means

Raised when the FFmpeg proxy-generation subprocess runs to completion but exits with a non-zero return code. The last 500 characters of FFmpeg's stderr (newlines flattened) are appended to the message, so the detail string carries the actual FFmpeg diagnostic; read it first.

Source

Thrown at app/services/sonilo.py:192

    ]
    try:
        result = subprocess.run(
            command,
            capture_output=True,
            text=True,
            timeout=600,
            check=False,
        )
    except subprocess.TimeoutExpired as exc:
        _remove_file(proxy_path)
        raise SoniloError("Sonilo video proxy generation timed out") from exc
    except OSError as exc:
        _remove_file(proxy_path)
        raise SoniloError("failed to run FFmpeg for Sonilo video proxy") from exc
    if result.returncode != 0:
        _remove_file(proxy_path)
        detail = (result.stderr or "").strip().replace("\n", " ")[-500:]
        raise SoniloError(f"failed to generate Sonilo video proxy: {detail}")
    proxy_size = os.path.getsize(proxy_path) if os.path.isfile(proxy_path) else 0
    if proxy_size <= 0 or proxy_size > MAX_PROXY_BYTES:
        _remove_file(proxy_path)
        raise SoniloError("Sonilo video proxy is empty or exceeds the 300 MB limit")
    logger.info(
        f"Sonilo video proxy prepared: source={video_path}, size={proxy_size} bytes"
    )
    return proxy_path


def _parse_event(raw_line: bytes) -> dict[str, Any]:
    """严格解析单条 NDJSON,禁止静默忽略截断或非对象响应。"""
    try:
        event = json.loads(raw_line.decode("utf-8"))
    except (UnicodeDecodeError, json.JSONDecodeError) as exc:
        raise SoniloError("Sonilo returned malformed streaming data") from exc
    if not isinstance(event, dict) or not isinstance(event.get("type"), str):
        raise SoniloError("Sonilo returned an invalid streaming event")

View on GitHub (pinned to 1f9f19c202)

Solutions

  1. Read the detail suffix; it is verbatim FFmpeg stderr and names the exact failure (codec, corruption, I/O).
  2. Reproduce manually: run the same ffmpeg command with the source file to see the full stderr.
  3. If the detail mentions invalid data or a missing moov atom, the upload is corrupt; re-upload or validate uploads before task creation.
  4. If the detail mentions no space left, free or enlarge the temp/task storage volume.

Example fix

# manual reproduction to see full stderr
ffmpeg -i corrupted.mp4 -f null - 2>&1 | tail -20
Defensive patterns

Strategy: try-catch

Validate before calling

# smoke-test the source before task creation
subprocess.run(
    ["ffmpeg", "-v", "error", "-i", video_path, "-f", "null", "-"],
    capture_output=True, timeout=120, check=True,
)  # raises CalledProcessError on corrupt input before the task starts

Try / catch

try:
    proxy = generate_video_proxy(video)
except SoniloError as exc:
    if str(exc).startswith("failed to generate Sonilo video proxy:"):
        detail = str(exc).rsplit(":", 1)[-1]
        if "Invalid data" in detail or "moov" in detail:
            reject_upload_as_corrupt(video)
        elif "space" in detail.lower():
            ops_alert_disk_full()
    raise

Prevention

When it happens

Trigger: Source video is corrupt or truncated (FFmpeg reports Invalid data found when processing input); unsupported codec or container for the requested proxy arguments; output path on a full disk (No space left on device); a stream the proxy filter chain cannot handle such as an audio-only file with no video stream.

Common situations: User uploads a file renamed to .mp4 that is actually something else or was only partially uploaded; the disk volume holding the task temp dir is full; the FFmpeg version on the host lacks a codec the command assumes.

Related errors


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