{"record":{"id":"762b55871ff421f8","repo":"unslothai/unsloth","slug":"no-export-subprocess-running","errorCode":null,"errorMessage":"No export subprocess running","messagePattern":"No export subprocess running","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"studio/backend/core/export/orchestrator.py","lineNumber":330,"sourceCode":"        logger.info(\"Export subprocess shut down\")\n        return True\n\n    def _cleanup(self):\n        \"\"\"atexit handler.\"\"\"\n        self._shutdown_subprocess(timeout = 5.0)\n\n    def _ensure_subprocess_alive(self) -> bool:\n        \"\"\"Check if subprocess is alive.\"\"\"\n        return self._proc is not None and self._proc.is_alive()\n\n    # ------------------------------------------------------------------\n    # Queue helpers\n    # ------------------------------------------------------------------\n\n    def _send_cmd(self, cmd: dict) -> None:\n        \"\"\"Send a command to the subprocess.\"\"\"\n        if self._cmd_queue is None:\n            raise RuntimeError(\"No export subprocess running\")\n        try:\n            self._cmd_queue.put(cmd)\n        except (OSError, ValueError) as exc:\n            raise RuntimeError(f\"Failed to send command to subprocess: {exc}\")\n\n    def _read_resp(self, timeout: float = 1.0) -> Optional[dict]:\n        \"\"\"Read a response from the subprocess (non-blocking with timeout).\"\"\"\n        if self._resp_queue is None:\n            return None\n        try:\n            return self._resp_queue.get(timeout = timeout)\n        except queue.Empty:\n            return None\n        except (EOFError, OSError, ValueError):\n            return None\n\n    def _wait_response(\n        self,","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/export/orchestrator.py#L312-L348","documentation":"Raised by ExportOrchestrator._send_cmd when a command is sent but the multiprocessing Queue to the export worker was never created (self._cmd_queue is None). It means no export subprocess was started — or it was already shut down — before an operation tried to talk to it. This is a lifecycle/sequencing error, not a subprocess failure.","triggerScenarios":"Calling run_export() or any path that calls _send_cmd() before load_checkpoint()/start has spawned the worker; calling _send_cmd() after _shutdown_subprocess() or after a crash path that cleared _cmd_queue; sending a second command after a failed checkpoint load that tore the subprocess down.","commonSituations":"API/route calls export before load; retry logic re-enters export after a previous export's cleanup ran; startup race where the client issues export immediately while the backend still initializing; worker teardown running concurrently with a queued op.","solutions":["Ensure load_checkpoint() (which spawns the subprocess and creates _cmd_queue) has completed successfully before issuing any export command","Guard every command-sending call site with _ensure_subprocess_alive() and re-load the checkpoint when it returns False","Check the orchestrator state (e.g. is_export_active / worker-alive flags) at the route level and return a 409-style 'load a checkpoint first' response instead of letting the RuntimeError escape","If this happens after a crash, inspect the backend log for the earlier 'Export subprocess crashed' / shutdown event that cleared the queue"],"exampleFix":"// before\norchestrator.run_export('gguf', params)\n\n// after\nif not orchestrator._ensure_subprocess_alive():\n    ok, msg = orchestrator.load_checkpoint(...)\n    if not ok:\n        raise RuntimeError(msg)\norchestrator.run_export('gguf', params)","handlingStrategy":"validation","validationCode":"def can_send_export_cmd(orch) -> bool:\n    return orch._cmd_queue is not None and orch._ensure_subprocess_alive()","typeGuard":null,"tryCatchPattern":"try:\n    orch.run_export(...)\nexcept RuntimeError as e:\n    if str(e) == \"No export subprocess running\":\n        ok, msg = orch.load_checkpoint(last_load_params)\n        # retry once after successful load\n    raise","preventionTips":["Always complete load_checkpoint before issuing export commands","Expose and check a worker-alive flag at the API layer and return 409 instead of raising","Serialize export start/stop so shutdown cannot clear the queue mid-op"],"tags":["export","subprocess","lifecycle","orchestrator"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}