{"record":{"id":"29657c7c6fcfdec6","repo":"unslothai/unsloth","slug":"failed-to-get-export-status","errorCode":null,"errorMessage":"Failed to get export status","messagePattern":"Failed to get export status","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"studio/backend/routes/export.py","lineNumber":198,"sourceCode":"        last_op_output_path = None\n        if last_op and last_op.get(\"output_path\"):\n            details = await asyncio.to_thread(_export_details, last_op[\"output_path\"])\n            last_op_output_path = (details or {}).get(\"output_path\")\n        return ExportStatusResponse(\n            current_checkpoint = backend.current_checkpoint,\n            is_vision = bool(getattr(backend, \"is_vision\", False)),\n            is_peft = bool(getattr(backend, \"is_peft\", False)),\n            is_export_active = bool(backend.is_export_active()),\n            active_op_kind = backend.get_active_op_kind(),\n            last_op_seq = int(last_op[\"seq\"]) if last_op else 0,\n            last_op_kind = last_op.get(\"kind\") if last_op else None,\n            last_op_status = last_op.get(\"status\") if last_op else None,\n            last_op_output_path = last_op_output_path,\n            last_op_error = last_op.get(\"error\") if last_op else None,\n        )\n    except Exception as e:\n        logger.error(f\"Error getting export status: {e}\", exc_info = True)\n        raise HTTPException(\n            status_code = 500,\n            detail = \"Failed to get export status\",\n        )\n\n\n@router.get(\"/logs\")\nasync def get_export_logs(\n    since: Optional[int] = Query(\n        None,\n        description = \"Return log entries with seq strictly greater than this cursor.\",\n    ),\n    current_subject: str = Depends(get_current_subject),\n):\n    \"\"\"Tunnel-safe JSON fallback for the live export log stream.\n\n    The SSE endpoint (`/logs/stream`) is the low-latency path, but some reverse\n    proxies -- notably Cloudflare quick tunnels (`*.trycloudflare.com`) used by\n    `--secure` mode -- buffer `text/event-stream` responses and only flush when","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/export.py#L180-L216","documentation":"Catch-all HTTP 500 for GET /export/status: assembling ExportStatusResponse (last op seq/kind/status/output path, active flags, vision/PEFT attributes) raised unexpectedly. The traceback is logged; the client gets the generic message. Since this is a read endpoint, it is not gated by _ensure_export_supported.","triggerScenarios":"GET /export/status when get_export_backend(), get_last_op(), or is_export_active() throws — e.g. backend singleton not yet initialized, or a corrupted last-op record with a non-int seq (the int(last_op['seq']) cast).","commonSituations":"Polling status immediately after backend startup before init completes; a state file written by an older version with a different schema.","solutions":["Check server logs for 'Error getting export status' with traceback.","Retry once after a short delay — startup races often self-resolve.","If a corrupted state file is implicated, remove/reset the export backend's persisted state and let it reinitialize."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await api.get('/export/status');\n} catch (e) {\n  if (e.status === 500 && firstAttempt) { await sleep(1000); return retry(); }\n  throw e;\n}","preventionTips":["Retry status once after startup — initialization races often clear.","Keep dashboard polling resilient: one 500 should not break the page."],"tags":["export","http-500","status","logging"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}