unslothai/unsloth · error · ValueError

Invalid base64 media data: {exc}

Error message

Invalid base64 media data: {exc}

What it means

base64.b64decode raised binascii.Error/ValueError while decoding the reference media payload, and _decode_b64_media re-wraps it as ValueError with the underlying reason. validate=False means only genuinely malformed input (wrong length, non-base64 alphabet characters after the data: prefix split) triggers this.

Source

Thrown at studio/backend/core/inference/video.py:421

# Enough for a 15-second reference video after base64 decoding.
_MAX_REFERENCE_MEDIA_BYTES = 96 * 1024 * 1024


def _decode_b64_media(data: Optional[str]) -> bytes:
    """Decode a base64 media payload, optionally wrapped in a data URL."""
    import base64
    import binascii

    raw = (data or "").strip()
    if not raw:
        raise ValueError("A reference was sent empty.")
    if raw.startswith("data:"):
        _, _, raw = raw.partition(",")
    try:
        blob = base64.b64decode(raw, validate = False)
    except (binascii.Error, ValueError) as exc:
        raise ValueError(f"Invalid base64 media data: {exc}") from exc
    if not blob:
        raise ValueError("A reference decoded to no data.")
    if len(blob) > _MAX_REFERENCE_MEDIA_BYTES:
        raise ValueError(
            f"A reference is too large ({len(blob) / 1e6:.0f} MB); the limit is "
            f"{_MAX_REFERENCE_MEDIA_BYTES / 1e6:.0f} MB."
        )
    return blob


class _VideoGenerationCancelled(Exception):
    """Unwinds a denoise loop that has no cooperative interrupt (no step callback);
    generate() maps it to the VIDEO_CANCELLED_MSG sentinel the routes 409 on."""


@contextlib.contextmanager
def _scheduler_step_progress(pipe: Any, on_step: Any):
    """Progress + cancellation for pipelines WITHOUT callback_on_step_end.

View on GitHub (pinned to 203007d190)

Solutions

  1. Encode the media properly: base64.b64encode(open(file,'rb').read()).decode('ascii').
  2. For data URLs, keep the standard form 'data:<mime>;base64,<payload>' so partition(',') finds the right split.
  3. Validate with a client-side b64decode before sending.

Example fix

# before
payload['reference_video'] = raw_bytes.decode('latin-1')  # not base64

# after
import base64
payload['reference_video'] = base64.b64encode(raw_bytes).decode('ascii')
Defensive patterns

Strategy: validation

Validate before calling

import base64, binascii

def is_valid_b64(ref: str | None) -> bool:
    if not ref or not ref.strip():
        return False
    raw = ref.strip()
    if raw.startswith('data:'):
        raw = raw.partition(',')[2]
    try:
        return len(base64.b64decode(raw)) > 0
    except (binascii.Error, ValueError):
        return False

Type guard

def is_b64_media(value: str) -> bool:
    raw = value.strip()
    if raw.startswith('data:'):
        raw = raw.partition(',')[2]
    try:
        base64.b64decode(raw)
        return True
    except (binascii.Error, ValueError):
        return False

Try / catch

try:
    blob = _decode_b64_media(ref)
except ValueError as e:
    if 'Invalid base64' in str(e):
        raise UserPayloadError(f'bad reference encoding: {e}') from e
    raise

Prevention

When it happens

Trigger: Sending a reference that is not valid base64: raw binary bytes, a URL-encoded file, truncated base64, or a data URL whose header portion contains characters outside the base64 alphabet because partition(',') split at the wrong comma.

Common situations: Reading a file as text instead of base64-encoding it; double-encoding or half-decoding in a proxy; hand-truncated payloads in tests; a data URL with a comma inside the MIME parameters.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/c5d82f4e3a6a14dc. Report an issue: GitHub.