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
- Encode the media properly: base64.b64encode(open(file,'rb').read()).decode('ascii').
- For data URLs, keep the standard form 'data:<mime>;base64,<payload>' so partition(',') finds the right split.
- 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
- Always encode binary media with base64.b64encode(...).decode('ascii').
- Use the canonical 'data:<mime>;base64,<payload>' shape so the comma split is unambiguous.
- Run a client-side b64decode round-trip before sending.
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
- A reference was sent empty.
- A reference decoded to no data.
- A reference is too large ({len(blob) / 1e6:.0f} MB); the lim
- each reference must be at most 32 MiB (base64)
- Invalid base64 image data: {exc}
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/c5d82f4e3a6a14dc.
Report an issue: GitHub.