unslothai/unsloth · error · HTTPException

unsupported file type: {ext}. allowed: {allowed}

Error message

unsupported file type: {ext}. allowed: {allowed}

What it means

Raised by the seed upload inspect endpoint when seed_source_type is 'unstructured' but the uploaded file's extension is not .txt or .md. The legacy single-file unstructured path intentionally accepts only plain-text formats; PDF/DOCX must go through the multi-file upload endpoint. It is an HTTP 400 FastAPI HTTPException, so the client sees a structured {detail: ...} body.

Source

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

            for fid in payload.file_ids
        ]
        return SeedInspectResponse(
            dataset_name = "unstructured_seed",
            resolved_path = resolved_paths[0] if resolved_paths else "",
            resolved_paths = resolved_paths,
            columns = columns,
            preview_rows = _serialize_preview_rows(preview_rows),
        )

    seed_source_type = _normalize_optional_text(payload.seed_source_type) or "local"
    filename = _sanitize_filename(payload.filename)
    ext = Path(filename).suffix.lower()
    # Legacy single-file path is .txt/.md only; PDF/DOCX use multi-file upload
    _LEGACY_UNSTRUCTURED_EXTS = {".txt", ".md"}
    if seed_source_type == "unstructured":
        if ext not in _LEGACY_UNSTRUCTURED_EXTS:
            allowed = ", ".join(sorted(_LEGACY_UNSTRUCTURED_EXTS))
            raise HTTPException(
                status_code = 400,
                detail = f"unsupported file type: {ext}. allowed: {allowed}",
            )
    else:
        if ext not in LOCAL_UPLOAD_EXTS:
            allowed = ", ".join(sorted(LOCAL_UPLOAD_EXTS))
            raise HTTPException(
                status_code = 400,
                detail = f"unsupported file type: {ext}. allowed: {allowed}",
            )

    file_bytes = _decode_base64_payload(payload.content_base64)
    if not file_bytes:
        raise HTTPException(status_code = 400, detail = "empty upload payload")
    if len(file_bytes) > LOCAL_SEED_UPLOAD_MAX_BYTES:
        raise HTTPException(
            status_code = 413,
            detail = f"file too large (max {LOCAL_SEED_UPLOAD_MAX_LABEL})",

View on GitHub (pinned to 203007d190)

Solutions

  1. Send PDF/DOCX files through the multi-file upload endpoint instead of the legacy single-file path.
  2. If the file is genuinely plain text, save it with a .txt or .md extension and retry.
  3. In the client, branch on file extension before choosing the endpoint: txt/md -> single-file, pdf/docx -> multi-file.

Example fix

// before
await api.post('/data-recipe/seed/inspect', {
  seed_source_type: 'unstructured',
  filename: 'report.pdf',
  content_base64: b64,
});

// after
await api.post('/data-recipe/seed/upload-multi', {
  files: [b64Pdf],
});
Defensive patterns

Strategy: validation

Validate before calling

const LEGACY_UNSTRUCTURED_EXTS = ['.txt', '.md'];
const ext = filename.slice(filename.lastIndexOf('.')).toLowerCase();
if (seedSourceType === 'unstructured' && !LEGACY_UNSTRUCTURED_EXTS.includes(ext)) {
  throw new Error(`use multi-file upload for ${ext}`);
}

Prevention

When it happens

Trigger: POST to the seed inspect route with payload.seed_source_type='unstructured' and payload.filename ending in .pdf, .docx, .csv, .json, or any extension outside {'.txt','.md'}. The extension is taken from Path(filename).suffix.lower() after filename sanitization.

Common situations: Frontends still wired to the legacy single-file upload sending PDFs; users renaming a .pdf to .txt (accepted here but fails later at parse); a client that defaults seed_source_type to 'unstructured' for all files.

Related errors


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