{"record":{"id":"2eb543126380c436","repo":"unslothai/unsloth","slug":"file-exceeds-the-cap-1024-1024-mb-upload","errorCode":null,"errorMessage":"File exceeds the {cap // (1024 * 1024)} MB upload limit.","messagePattern":"File exceeds the (.+?) MB upload limit\\.","errorType":"http","errorClass":"HTTPException","httpStatus":413,"severity":"warning","filePath":"studio/backend/routes/rag.py","lineNumber":140,"sourceCode":"    stored_path = str(uploads / f\"{uuid.uuid4().hex}{ext}\")\n    size = 0\n    cap = config.MAX_UPLOAD_BYTES\n    try:\n        with open(stored_path, \"wb\") as out:\n            while True:\n                block = source.read(1 << 20)\n                if not block:\n                    break\n                size += len(block)\n                if cap and size > cap:\n                    break\n                out.write(block)\n    except OSError:\n        _remove_stored_upload(stored_path)\n        raise\n    if cap and size > cap:\n        _remove_stored_upload(stored_path)\n        raise HTTPException(\n            status_code = 413,\n            detail = f\"File exceeds the {cap // (1024 * 1024)} MB upload limit.\",\n        )\n    if size == 0:\n        _remove_stored_upload(stored_path)\n        raise HTTPException(status_code = 400, detail = empty_detail)\n    return stored_path, filename\n\n\ndef _save_upload(file: UploadFile) -> tuple[str, str]:\n    \"\"\"Persist a browser upload; returns (stored_path, filename).\"\"\"\n    filename = _sanitize_filename(file.filename or \"document\")\n    return _persist_upload_stream(\n        file.file,\n        filename,\n        empty_detail = \"Uploaded file is empty.\",\n    )\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/rag.py#L122-L158","documentation":"_persist_upload_stream() streams the upload to disk in 1 MiB blocks and enforces config.MAX_UPLOAD_BYTES; once the accumulated size exceeds the cap (checked both during streaming and after), the partially written file is removed and HTTP 413 is returned with the limit expressed in MB.","triggerScenarios":"Uploading a document larger than config.MAX_UPLOAD_BYTES (cap // (1024*1024) MB) — e.g. a multi-hundred-MB PDF or scan set against the configured limit. The write loop stops early and deletes the partial file.","commonSituations":"Large scanned PDFs, concatenated transcripts, or log exports exceed the default cap; an operator raised the client-side limit but not the server's config.MAX_UPLOAD_BYTES; a proxy in front also has its own body cap that can mask this error.","solutions":["Split or compress the document under the stated MB limit and re-upload.","If large documents are expected, raise config.MAX_UPLOAD_BYTES on the backend (and any reverse-proxy body limit) and restart.","Show the limit in the UI before upload starts so users do not wait for a full transfer to learn it."],"exampleFix":"# before\nupload('huge_scan_bundle.pdf')  # 413 File exceeds the N MB upload limit\n# after\n# backend config\nMAX_UPLOAD_BYTES = 512 * 1024 * 1024  # if 512 MB documents are supported","handlingStrategy":"validation","validationCode":"const MAX_BYTES = await getMaxUploadLimit(); // or mirror config.MAX_UPLOAD_BYTES\nif (file.size > MAX_BYTES) { notify(`File exceeds ${MAX_BYTES / 1024 / 1024} MB`); return; }","typeGuard":null,"tryCatchPattern":"if (res.status === 413) { suggestSplitting(file); return; }","preventionTips":["Check file.size before starting the upload; a full transfer wasted on a 413 is the worst outcome.","Keep client, backend config.MAX_UPLOAD_BYTES, and reverse-proxy body limits aligned.","Show the limit next to the drop zone."],"tags":["http-413","file-upload","size-limit","rag","studio-backend"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}