{"record":{"id":"052a368deb430713","repo":"unslothai/unsloth","slug":"unsupported-file-type-ext-allowed-allowed-052a36","errorCode":null,"errorMessage":"unsupported file type: {ext}. allowed: {allowed}","messagePattern":"unsupported file type: (.+?)\\. allowed: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"studio/backend/routes/data_recipe/seed.py","lineNumber":657,"sourceCode":"            for fid in payload.file_ids\n        ]\n        return SeedInspectResponse(\n            dataset_name = \"unstructured_seed\",\n            resolved_path = resolved_paths[0] if resolved_paths else \"\",\n            resolved_paths = resolved_paths,\n            columns = columns,\n            preview_rows = _serialize_preview_rows(preview_rows),\n        )\n\n    seed_source_type = _normalize_optional_text(payload.seed_source_type) or \"local\"\n    filename = _sanitize_filename(payload.filename)\n    ext = Path(filename).suffix.lower()\n    # Legacy single-file path is .txt/.md only; PDF/DOCX use multi-file upload\n    _LEGACY_UNSTRUCTURED_EXTS = {\".txt\", \".md\"}\n    if seed_source_type == \"unstructured\":\n        if ext not in _LEGACY_UNSTRUCTURED_EXTS:\n            allowed = \", \".join(sorted(_LEGACY_UNSTRUCTURED_EXTS))\n            raise HTTPException(\n                status_code = 400,\n                detail = f\"unsupported file type: {ext}. allowed: {allowed}\",\n            )\n    else:\n        if ext not in LOCAL_UPLOAD_EXTS:\n            allowed = \", \".join(sorted(LOCAL_UPLOAD_EXTS))\n            raise HTTPException(\n                status_code = 400,\n                detail = f\"unsupported file type: {ext}. allowed: {allowed}\",\n            )\n\n    file_bytes = _decode_base64_payload(payload.content_base64)\n    if not file_bytes:\n        raise HTTPException(status_code = 400, detail = \"empty upload payload\")\n    if len(file_bytes) > LOCAL_SEED_UPLOAD_MAX_BYTES:\n        raise HTTPException(\n            status_code = 413,\n            detail = f\"file too large (max {LOCAL_SEED_UPLOAD_MAX_LABEL})\",","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/data_recipe/seed.py#L639-L675","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Send PDF/DOCX files through the multi-file upload endpoint instead of the legacy single-file path.","If the file is genuinely plain text, save it with a .txt or .md extension and retry.","In the client, branch on file extension before choosing the endpoint: txt/md -> single-file, pdf/docx -> multi-file."],"exampleFix":"// before\nawait api.post('/data-recipe/seed/inspect', {\n  seed_source_type: 'unstructured',\n  filename: 'report.pdf',\n  content_base64: b64,\n});\n\n// after\nawait api.post('/data-recipe/seed/upload-multi', {\n  files: [b64Pdf],\n});","handlingStrategy":"validation","validationCode":"const LEGACY_UNSTRUCTURED_EXTS = ['.txt', '.md'];\nconst ext = filename.slice(filename.lastIndexOf('.')).toLowerCase();\nif (seedSourceType === 'unstructured' && !LEGACY_UNSTRUCTURED_EXTS.includes(ext)) {\n  throw new Error(`use multi-file upload for ${ext}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Branch client-side on extension: txt/md to the single-file endpoint, pdf/docx to multi-file upload.","Never rely on extension renaming to smuggle a format past the whitelist — the parser will reject it later with a worse error."],"tags":["validation","file-upload","fastapi","data-recipe"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}