unslothai/unsloth · warning · HTTPException

A transformers installation is in progress. Retry when it co

Error message

A transformers installation is in progress. Retry when it completes.

What it means

HTTP 409 raised by _ensure_export_supported (and every mutating export endpoint that depends on it) while a latest-transformers install is actively swapping the .venv_t5_latest sidecar. The guard exists because an export worker spawned mid-swap could activate a half-replaced virtual environment, corrupting the operation. It is by design retryable once the install finishes.

Source

Thrown at studio/backend/routes/export.py:60

    ExportLoRAAdapterRequest,
)

router = APIRouter()
logger = get_logger(__name__)


async def _ensure_export_supported() -> None:
    """Reject a mutating export request up front (HTTP 400) when the host can't export.

    Keeps the backend authoritative even if a client bypasses the UI gate. Read-only endpoints
    (scan/status/logs) are intentionally NOT gated so the Export page can still render the reason.
    Also refuses (409) while a latest-transformers install is swapping .venv_t5_latest: an
    export worker spawned mid-swap could activate a half-replaced sidecar.
    """
    from utils.transformers_latest import is_install_in_progress

    if is_install_in_progress():
        raise HTTPException(
            status_code = 409,
            detail = "A transformers installation is in progress. Retry when it completes.",
        )

    from utils.hardware import export_capability

    # Off-loop: detection is deferred past bind, so the first call can wait on a cold import.
    cap = await asyncio.to_thread(export_capability)
    if not cap.get("export_supported", True):
        raise HTTPException(
            status_code = 400,
            detail = cap.get("export_unsupported_message")
            or "Export is not supported on this platform.",
        )


@router.post("/load-checkpoint", response_model = ExportOperationResponse)
async def load_checkpoint(

View on GitHub (pinned to 203007d190)

Solutions

  1. Wait for the transformers install to finish (watch the install status endpoint/UI) and retry the export.
  2. On the client, treat 409 with this message as retryable with backoff rather than surfacing it as a hard failure.
  3. Serialize operations: block export buttons in the UI while an install is in progress, mirroring the backend gate.

Example fix

// before
const res = await api.post('/export/load-checkpoint', body);

// after
let res;
for (let i = 0; i < 5; i++) {
  res = await api.post('/export/load-checkpoint', body).catch(e => e);
  if (!(res.status === 409 && /installation is in progress/.test(res.detail))) break;
  await sleep(5000);
}
Defensive patterns

Strategy: retry

Validate before calling

const status = await api.get('/export/status'); // read-only, not gated
if (status.install_in_progress) await waitForInstallCompletion();

Try / catch

try {
  await api.post('/export/load-checkpoint', body);
} catch (e) {
  if (e.status === 409 && /installation is in progress/.test(e.detail)) {
    await sleep(backoffMs); return retry();
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling POST /export/load-checkpoint, /export/merged, /export/base, /export/gguf, or /cleanup while utils.transformers_latest.is_install_in_progress() returns True — i.e. a transformers upgrade was started from the UI or CLI and has not completed.

Common situations: User kicks off a transformers version upgrade, then immediately retries an export from another tab; an automated script that fires export requests without checking install status; long installs on slow networks colliding with scheduled exports.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/858b6280bb77c6d7. Report an issue: GitHub.