{"record":{"id":"50cd4837acb2cb82","repo":"unslothai/unsloth","slug":"total-upload-limit-unstructured-recipe-upload-to","errorCode":null,"errorMessage":"Total upload limit ({UNSTRUCTURED_RECIPE_UPLOAD_TOTAL_MAX_LABEL}) exceeded","messagePattern":"Total upload limit \\((.+?)\\) exceeded","errorType":"http","errorClass":"HTTPException","httpStatus":413,"severity":"error","filePath":"studio/backend/routes/data_recipe/seed.py","lineNumber":466,"sourceCode":"        )\n\n    content = await file.read()\n    size_bytes = len(content)\n\n    if size_bytes == 0:\n        raise HTTPException(400, \"Empty file not allowed\")\n\n    if size_bytes > UNSTRUCTURED_RECIPE_UPLOAD_MAX_BYTES:\n        raise HTTPException(\n            413,\n            f\"File too large ({size_bytes} bytes). Maximum is {UNSTRUCTURED_RECIPE_UPLOAD_MAX_LABEL}.\",\n        )\n\n    block_dir = UNSTRUCTURED_UPLOAD_ROOT / block_id\n    ensure_dir(block_dir)\n    current_total = _get_block_total_size(block_dir)\n    if current_total + size_bytes > UNSTRUCTURED_RECIPE_UPLOAD_TOTAL_MAX_BYTES:\n        raise HTTPException(\n            413,\n            f\"Total upload limit ({UNSTRUCTURED_RECIPE_UPLOAD_TOTAL_MAX_LABEL}) exceeded\",\n        )\n\n    file_id = uuid4().hex\n    raw_path = block_dir / f\"{file_id}{ext}\"\n    raw_path.write_bytes(content)\n\n    extracted_path = block_dir / f\"{file_id}.extracted.txt\"\n    try:\n        extracted_text = _extract_text_from_file(raw_path, ext)\n        if not extracted_text or not extracted_text.strip():\n            raw_path.unlink(missing_ok = True)\n            return UnstructuredFileUploadResponse(\n                file_id = file_id,\n                filename = original_filename,\n                size_bytes = size_bytes,\n                status = \"error\",","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/data_recipe/seed.py#L448-L484","documentation":"HTTP 413 raised by POST /seed/upload-unstructured-file when the sum of existing files in the block directory (via _get_block_total_size) plus the new upload would exceed UNSTRUCTURED_RECIPE_UPLOAD_TOTAL_MAX_BYTES. This is a per-block aggregate quota, separate from the per-file cap.","triggerScenarios":"Uploading a file to block_id X when files already uploaded to that block total near the aggregate limit; the new file pushes current_total + size_bytes over the cap.","commonSituations":"Iteratively adding documents to the same block during recipe editing; orphaned uploads from deleted blocks still counting toward quota (docstring notes files on disk still count); users not realizing the quota is cumulative per block.","solutions":["Free space: DELETE /seed/unstructured-file/{block_id}/{file_id} for files no longer needed, or DELETE /seed/unstructured-block/{block_id} to purge a uid-namespaced block.","Move excess documents into a second block rather than exceeding one block's quota.","Shrink/compress remaining files to fit under the total cap."],"exampleFix":"# before\nupload(block_id='abc...', file=extra.pdf)  # total would exceed cap\n\n# after\nawait deleteFile(blockId, unusedFileId);  # free quota first\nupload(block_id='abc...', file=extra.pdf);","handlingStrategy":"validation","validationCode":"const blockTotal = await getBlockTotalSize(blockId); // from block listing\nif (blockTotal + file.size > TOTAL_MAX) throw new Error(`block quota would exceed ${TOTAL_MAX}; delete files first`);","typeGuard":null,"tryCatchPattern":"On 413 'Total upload limit exceeded', offer the user a file-picker to delete existing block files, then retry the upload of only the needed files.","preventionTips":["Track cumulative block size in the UI and warn before the cap.","Purge unused uid-namespaced blocks after recipes are deleted."],"tags":["upload","quota","http-413","unstructured"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}