unslothai/unsloth · error · HTTPException
Failed to get export status
Error message
Failed to get export status
What it means
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.
Source
Thrown at studio/backend/routes/export.py:198
last_op_output_path = None
if last_op and last_op.get("output_path"):
details = await asyncio.to_thread(_export_details, last_op["output_path"])
last_op_output_path = (details or {}).get("output_path")
return ExportStatusResponse(
current_checkpoint = backend.current_checkpoint,
is_vision = bool(getattr(backend, "is_vision", False)),
is_peft = bool(getattr(backend, "is_peft", False)),
is_export_active = bool(backend.is_export_active()),
active_op_kind = backend.get_active_op_kind(),
last_op_seq = int(last_op["seq"]) if last_op else 0,
last_op_kind = last_op.get("kind") if last_op else None,
last_op_status = last_op.get("status") if last_op else None,
last_op_output_path = last_op_output_path,
last_op_error = last_op.get("error") if last_op else None,
)
except Exception as e:
logger.error(f"Error getting export status: {e}", exc_info = True)
raise HTTPException(
status_code = 500,
detail = "Failed to get export status",
)
@router.get("/logs")
async def get_export_logs(
since: Optional[int] = Query(
None,
description = "Return log entries with seq strictly greater than this cursor.",
),
current_subject: str = Depends(get_current_subject),
):
"""Tunnel-safe JSON fallback for the live export log stream.
The SSE endpoint (`/logs/stream`) is the low-latency path, but some reverse
proxies -- notably Cloudflare quick tunnels (`*.trycloudflare.com`) used by
`--secure` mode -- buffer `text/event-stream` responses and only flush whenView on GitHub (pinned to 203007d190)
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.
Defensive patterns
Strategy: retry
Try / catch
try {
return await api.get('/export/status');
} catch (e) {
if (e.status === 500 && firstAttempt) { await sleep(1000); return retry(); }
throw e;
} Prevention
- Retry status once after startup — initialization races often clear.
- Keep dashboard polling resilient: one 500 should not break the page.
When it happens
Trigger: 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).
Common situations: Polling status immediately after backend startup before init completes; a state file written by an older version with a different schema.
Related errors
- Failed to load checkpoint
- Failed to get export logs
- Failed to export merged model
- Failed to list local models: {str(e)}
- Memory cleanup failed. See server logs for details.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/29657c7c6fcfdec6.
Report an issue: GitHub.