{"record":{"id":"a9abc703ee3747fe","repo":"unslothai/unsloth","slug":"a-diffusion-load-is-already-in-progress-a9abc7","errorCode":null,"errorMessage":"A diffusion load is already in progress.","messagePattern":"A diffusion load is already in progress\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"studio/backend/core/inference/sd_cpp_backend.py","lineNumber":1233,"sourceCode":"        # native engine does not read the diffusers base: FLUX.2 takes its VAE from\n        # unsloth/FLUX.2-VAE and its encoders from another repo again, so recording only the base\n        # left every repo the pick really depends on outside the guard, and an unloaded model's\n        # encoder could be deleted while its GGUF stayed installed. Best-effort bookkeeping;\n        # never fails a load.\n        try:\n            from hub.utils.companion_assets import record_companion_link\n            for asset_repo in dict.fromkeys(\n                r\n                for r, _f, kind in self._asset_specs(repo_id, gguf_filename, fam, inner_dim)\n                if kind != \"diffusion_model\"\n            ):\n                record_companion_link(repo_id, asset_repo)\n            record_companion_link(repo_id, base)\n        except Exception as exc:  # noqa: BLE001\n            logger.debug(\"sd_cpp.companion_link_record_failed: %s\", exc)\n        with self._lock:\n            if self._loading is not None and self._loading.error is None:\n                raise RuntimeError(\"A diffusion load is already in progress.\")\n            # A superseding load must stop any in-flight generation, else the old run can still persist an image after the new load starts.\n            if self._active_generate_cancel is not None:\n                self._active_generate_cancel.set()\n            self._load_token += 1\n            token = self._load_token\n            # A NEW event per load, never a clear() of the shared one: unload() sets the event the running worker holds but also\n            # drops _loading, so a clear() here would un-cancel its still-running multi-gigabyte pull.\n            cancel_event = threading.Event()\n            self._cancel_event = cancel_event\n            self._loading = _SdLoading(\n                repo_id = repo_id,\n                base_repo = base,\n                asset_repos = tuple(\n                    dict.fromkeys(\n                        r\n                        for r, _f, kind in self._asset_specs(repo_id, gguf_filename, fam, inner_dim)\n                        if kind != \"diffusion_model\"\n                    )","sourceCodeStart":1215,"sourceCodeEnd":1251,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/sd_cpp_backend.py#L1215-L1251","documentation":"RuntimeError raised under the backend lock when begin_load is called while a previous load is still in flight (self._loading is set without an error). One diffusion load at a time is enforced; the second caller fails fast instead of interleaving downloads/state swaps.","triggerScenarios":"Two concurrent begin_load calls on the same backend instance (double-clicked load in UI, parallel MCP requests, retry fired before the first load finished).","commonSituations":"Frontends that fire load on every settings change; automation retrying a slow load without waiting; UI not disabling the load button during a load.","solutions":["Wait for the in-flight load to finish (poll status()) before calling begin_load again.","Fix the caller so only one load is issued at a time (disable the button / serialize requests).","If the stuck load never completes, call unload() to clear the in-flight state, then reload."],"exampleFix":"# before\nbackend.begin_load(repo_a, gguf_a)  # still running\nbackend.begin_load(repo_b, gguf_b)  # RuntimeError\n\n# after\nwhile backend.status().get('loading'):\n    time.sleep(0.5)\nbackend.begin_load(repo_b, gguf_b)","handlingStrategy":"validation","validationCode":"status = backend.status()\nif status.get('loading'):\n    wait_for_load_complete(backend)  # poll status until not loading","typeGuard":null,"tryCatchPattern":"try:\n    backend.begin_load(repo_id=r, gguf_filename=f)\nexcept RuntimeError as e:\n    if 'already in progress' in str(e):\n        wait_for_load_complete(backend)\n        backend.begin_load(repo_id=r, gguf_filename=f)\n    else:\n        raise","preventionTips":["Serialize begin_load calls behind a queue or mutex in the client.","Disable the load button in the UI while status() reports a load in flight."],"tags":["concurrency","state-machine","load"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}