{"record":{"id":"64f16a2ab167d70e","repo":"unslothai/unsloth","slug":"failed-to-export-base-model","errorCode":null,"errorMessage":"Failed to export base model","messagePattern":"Failed to export base model","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"studio/backend/routes/export.py","lineNumber":388,"sourceCode":"\n        if not success:\n            raise HTTPException(status_code = 400, detail = message)\n\n        return ExportOperationResponse(\n            success = True,\n            message = message,\n            details = await asyncio.to_thread(_export_details, output_path, refresh_index = True),\n        )\n    except HTTPException:\n        raise\n    except Exception as e:\n        from utils.transformers_version import SidecarSwapInProgress\n\n        if isinstance(e, SidecarSwapInProgress):\n            # Expected loss of the race against a sidecar install: retryable 409.\n            raise HTTPException(status_code = 409, detail = str(e))\n        logger.error(f\"Error exporting base model: {e}\", exc_info = True)\n        raise HTTPException(\n            status_code = 500,\n            detail = \"Failed to export base model\",\n        )\n\n\n@router.post(\"/export/gguf\", response_model = ExportOperationResponse)\nasync def export_gguf(\n    request: ExportGGUFRequest, current_subject: str = Depends(get_current_subject)\n):\n    \"\"\"Export the current model to GGUF format, optionally pushing to Hub.\n\n    Wraps ExportBackend.export_gguf.\n    \"\"\"\n    try:\n        await _ensure_export_supported()\n        backend = get_export_backend()\n        # A custom path wins; otherwise the imatrix toggle requests the upstream auto-download.\n        imatrix_file = request.imatrix_path or (True if request.imatrix else None)","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/export.py#L370-L406","documentation":"Generic 500 raised by the POST base-model export endpoint when the backend export call throws an unexpected exception. The handler first re-raises HTTPExceptions as-is and converts SidecarSwapInProgress into a 409, so this 500 means a genuinely unhandled failure inside ExportBackend's base export (run in a worker thread). The original exception is logged server-side with a full traceback via logger.error(..., exc_info=True).","triggerScenarios":"POST to the base-model export route while no model is loaded in the trainer, when the save directory is unwritable or full, when the underlying transformers/unsloth export crashes (OOM, corrupt checkpoint, incompatible model class), or when _export_details fails after a successful export.","commonSituations":"Exporting right after a crashed training run, exporting a model that was swapped/unloaded by another request, disk exhaustion in the output directory, or a version-mismatched transformers install breaking the export path.","solutions":["Read the backend log for the 'Error exporting base model:' line — the exc_info traceback names the real cause; fix that first.","Confirm a model is actually loaded (check the trainer/model state endpoint) before issuing the export.","Verify the target save_directory exists and is writable and has free disk space.","If the log shows SidecarSwapInProgress but you still got a 500, check for a stale sidecar install and let it finish, then retry.","Reproduce with the same parameters from a notebook/script to surface the underlying traceback directly."],"exampleFix":"// before\nconst r = await fetch('/api/export/base', {method:'POST', body: JSON.stringify({save_directory: '/out'})});\nif (!r.ok) console.error(await r.text()); // opaque 'Failed to export base model'\n\n// after\nconst r = await fetch('/api/export/base', {method:'POST', body: JSON.stringify({save_directory: '/out'})});\nif (r.status === 500) {\n  // server log carries the traceback; surface actionable context to the user\n  throw new Error('Export failed — check backend log and that a model is loaded');\n}","handlingStrategy":"try-catch","validationCode":"const state = await api.get('/api/trainer/state').then(r => r.json());\nif (!state.model_loaded) throw new Error('Load a model before exporting');","typeGuard":null,"tryCatchPattern":"try {\n  const r = await api.post('/api/export/base', body);\n} catch (e) {\n  if (e.status === 500) { /* read backend log; show 'export failed, see server log' */ }\n  else throw e;\n}","preventionTips":["Always confirm a model is loaded before calling export endpoints.","Keep disk space and write permissions on the export directory verified.","Never change transformers versions concurrently with an export."],"tags":["export","http-500","fastapi","unsloth"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}