unslothai/unsloth · error · HTTPException

invalid base64 payload

Error message

invalid base64 payload

What it means

HTTP 400 raised by _decode_base64_payload when base64.b64decode(raw, validate=True) raises binascii.Error — the payload contains characters outside the base64 alphabet or has wrong padding. The function first strips an optional data-URL prefix (data:...;base64,) before decoding.

Source

Thrown at studio/backend/routes/data_recipe/seed.py:198

            columns_seen[str(key)] = None
    return list(columns_seen.keys())


def _sanitize_filename(filename: str) -> str:
    name = Path(filename).name.strip().replace("\x00", "")
    if not name:
        return "seed_upload"
    return name


def _decode_base64_payload(content_base64: str) -> bytes:
    raw = content_base64.strip()
    if "," in raw and raw.lower().startswith("data:"):
        raw = raw.split(",", 1)[1]
    try:
        return base64.b64decode(raw, validate = True)
    except binascii.Error as exc:
        raise HTTPException(status_code = 400, detail = "invalid base64 payload") from exc


def _read_preview_rows_from_local_file(path: Path, preview_size: int) -> list[dict[str, Any]]:
    try:
        import pandas as pd
    except ImportError as exc:
        raise log_and_http_error(
            exc,
            500,
            "seed inspect dependencies unavailable",
            event = "data_recipe.seed.dependencies_unavailable",
            log = logger,
        ) from exc

    ext = path.suffix.lower()
    try:
        if ext == ".csv":
            df = pd.read_csv(path, nrows = preview_size, encoding = "utf-8-sig")

View on GitHub (pinned to 203007d190)

Solutions

  1. Send standard (not URL-safe) base64 with correct padding = signs.
  2. If you have a data-URL, include the comma: 'data:text/csv;base64,XXXX'.
  3. In Python, use base64.b64encode(data).decode('ascii'); in JS, btoa(binaryString) on the whole file.
  4. Log the payload length and first/last chars client-side to spot truncation or embedded newlines.

Example fix

# before (Python client)
requests.post(url, json={'content_base64': str(b64encode(blob))})  # sends "b'xxxx'"

# after
requests.post(url, json={'content_base64': b64encode(blob).decode('ascii')})
Defensive patterns

Strategy: validation

Validate before calling

const B64 = /^[A-Za-z0-9+/]+={0,2}$/;
function toStandardBase64(blob) {
  const buf = new Uint8Array(blob);
  let bin = ''; buf.forEach(b => bin += String.fromCharCode(b));
  return btoa(bin); // standard base64, padded
}
const payload = toStandardBase64(file);
if (!B64.test(payload)) throw new Error('encoding bug');

Type guard

function isStandardBase64(s: string): boolean {
  return /^[A-Za-z0-9+/]+={0,2}$/.test(s) && s.length % 4 === 0;
}

Try / catch

Catch the 400 response; if detail === 'invalid base64 payload', re-encode the file with a tested encoder and retry once. Do not retry with the same body.

Prevention

When it happens

Trigger: POST /seed upload with content_base64 that is not strictly base64: whitespace inside the string, URL-safe base64 (- and _) instead of standard (+ and /), missing padding, or a data-URL prefix not separated by a comma.

Common situations: Client uses btoa/atob incorrectly, sends base64url (common from crypto APIs), truncates the string, or double-encodes. Python clients passing raw bytes instead of str also fail.

Related errors


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