unslothai/unsloth · error · HTTPException

Unsupported file type: {ext}. Allowed: {', '.join(sorted(UNS

Error message

Unsupported file type: {ext}. Allowed: {', '.join(sorted(UNSTRUCTURED_ALLOWED_EXTS))}

What it means

HTTP 400 raised by POST /seed/upload-unstructured-file when the uploaded file's lowercased extension is not in UNSTRUCTURED_ALLOWED_EXTS = {.pdf, .docx, .txt, .md}. The extension comes from the original filename's suffix; other document formats are rejected before the bytes are even read.

Source

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

    for f in block_dir.iterdir():
        if not f.is_file():
            continue
        if f.name.endswith(".extracted.txt") or f.name.endswith(".meta.json"):
            continue
        total += f.stat().st_size
    return total


@router.post("/seed/upload-unstructured-file")
async def upload_unstructured_file(
    file: UploadFile = FastAPIFile(...), block_id: str = Form(...)
) -> UnstructuredFileUploadResponse:
    _validate_safe_id(block_id, "block_id")

    original_filename = file.filename or "upload"
    ext = Path(original_filename).suffix.lower()
    if ext not in UNSTRUCTURED_ALLOWED_EXTS:
        raise HTTPException(
            400,
            f"Unsupported file type: {ext}. Allowed: {', '.join(sorted(UNSTRUCTURED_ALLOWED_EXTS))}",
        )

    content = await file.read()
    size_bytes = len(content)

    if size_bytes == 0:
        raise HTTPException(400, "Empty file not allowed")

    if size_bytes > UNSTRUCTURED_RECIPE_UPLOAD_MAX_BYTES:
        raise HTTPException(
            413,
            f"File too large ({size_bytes} bytes). Maximum is {UNSTRUCTURED_RECIPE_UPLOAD_MAX_LABEL}.",
        )

    block_dir = UNSTRUCTURED_UPLOAD_ROOT / block_id
    ensure_dir(block_dir)

View on GitHub (pinned to 203007d190)

Solutions

  1. Convert the document to .pdf, .docx, .txt, or .md before upload.
  2. For .doc, re-save as .docx in Word/LibreOffice or export as PDF.
  3. Ensure the filename retains its extension — do not strip it when staging uploads.

Example fix

# before
libreoffice --convert-to doc old.doc  # still rejected

# after
libreoffice --convert-to pdf old.doc  # .pdf is allowed
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED = new Set(['.pdf', '.docx', '.txt', '.md']);
const ext = file.name.slice(file.name.lastIndexOf('.')).toLowerCase();
if (!ALLOWED.has(ext)) throw new Error(`unsupported: ${ext}; convert to pdf/docx/txt/md`);

Type guard

function isAllowedDoc(name: string): boolean {
  return ['.pdf', '.docx', '.txt', '.md'].includes(name.slice(name.lastIndexOf('.')).toLowerCase());
}

Try / catch

On 400 'Unsupported file type', filter the file out of the batch, tell the user which files need conversion, and upload the rest.

Prevention

When it happens

Trigger: Uploading .docx works, but .doc, .rtf, .odt, .pptx, .html, or an extension-less file fails immediately with this 400.

Common situations: Legacy .doc files from Word; user assumes 'any document' works; macOS 'file.pdf.download' style names; uppercase handled (code lowercases), so the failure is always a genuinely unsupported format.

Related errors


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