{"record":{"id":"7570f28163b543fe","repo":"microsoft/qlib","slug":"this-recorder-is-not-saved-in-the-local-file-syste","errorCode":null,"errorMessage":"This recorder is not saved in the local file system.","messagePattern":"This recorder is not saved in the local file system\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"qlib/workflow/recorder.py","lineNumber":328,"sourceCode":"\r\n    @property\r\n    def artifact_uri(self):\r\n        return self._artifact_uri\r\n\r\n    def get_local_dir(self):\r\n        \"\"\"\r\n        This function will return the directory path of this recorder.\r\n        \"\"\"\r\n        if self.artifact_uri is not None:\r\n            if platform.system() == \"Windows\":\r\n                local_dir_path = Path(self.artifact_uri.lstrip(\"file:\").lstrip(\"/\")).parent\r\n            else:\r\n                local_dir_path = Path(self.artifact_uri.lstrip(\"file:\")).parent\r\n            local_dir_path = str(local_dir_path.resolve())\r\n            if os.path.isdir(local_dir_path):\r\n                return local_dir_path\r\n            else:\r\n                raise RuntimeError(\"This recorder is not saved in the local file system.\")\r\n\r\n        else:\r\n            raise ValueError(\r\n                \"Please make sure the recorder has been created and started properly before getting artifact uri.\"\r\n            )\r\n\r\n    def start_run(self):\r\n        # set the tracking uri\r\n        mlflow.set_tracking_uri(self.uri)\r\n        # start the run\r\n        run = mlflow.start_run(self.id, self.experiment_id, self.name)\r\n        # save the run id and artifact_uri\r\n        self.id = run.info.run_id\r\n        self._artifact_uri = run.info.artifact_uri\r\n        self.start_time = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\r\n        self.status = Recorder.STATUS_R\r\n        logger.info(f\"Recorder {self.id} starts running under Experiment {self.experiment_id} ...\")\r\n\r","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/workflow/recorder.py#L310-L346","documentation":"MLflowRecorder.local_dir derives the recorder's on-disk directory from artifact_uri (stripping the file: prefix and taking the parent path). If that resolved path is not an existing local directory (os.path.isdir fails), it raises RuntimeError — the artifacts live somewhere that is not this machine's filesystem. A separate ValueError is raised when artifact_uri is None (run never started properly); this RuntimeError specifically means 'the URI resolved, but not to a local dir we can see'.","triggerScenarios":"MLflow tracking server with a remote artifact store (s3://, nfs, gs://, or a file path on another host) — artifact_uri then does not map to a local directory; artifacts root moved or deleted after the run; artifact_uri uses a file: path that was mounted elsewhere; reading a shared mlruns directory that is not mounted on this machine.","commonSituations":"Pointing MLFLOW_TRACKING_URI at a central server while artifacts default to the server-side ./mlruns; switching machines and losing the mount that previously held the artifacts; cleanup scripts deleting mlruns directories; artifact_location configured per-experiment to a remote scheme.","solutions":["Ensure artifacts are local: set the artifact root to a local/shared path when creating the experiment (mlflow.create_experiment(..., artifact_location='file:///mnt/shared/mlruns')) and mount it on the client machine","If you only need artifact contents, avoid local_dir and use recorder.load_object(name) / list_artifacts, which go through the MLflow artifact repo and work with remote stores","Verify the path exists: print recorder.artifact_uri, resolve it locally (strip file:), and check the mount; re-mount or fix permissions","Re-create or restore the mlruns artifact directory if it was deleted"],"exampleFix":"# before\n# MLflow server with server-side artifacts\nrec.local_dir()  # RuntimeError: not saved in local file system\n\n# after (option 1: local artifact root)\nmlflow.create_experiment('my_exp', artifact_location='file:///mnt/shared/mlruns/my_exp')\n# after (option 2: use artifact API instead of local path)\npred = rec.load_object('pred.pkl')","handlingStrategy":"validation","validationCode":"import os\nfrom pathlib import Path\n\ndef local_dir_safe(recorder) -> str:\n    uri = recorder.artifact_uri\n    if uri is None:\n        raise ValueError('recorder not started; no artifact_uri')\n    if not uri.startswith('file:'):\n        raise RuntimeError(f'artifacts are remote ({uri}); local_dir() unsupported')\n    p = str(Path(uri[len('file:'):]).parent.resolve())\n    if not os.path.isdir(p):\n        raise RuntimeError(f'artifact path {p} missing; check mounts')\n    return p","typeGuard":"import os\nfrom pathlib import Path\n\ndef has_local_artifacts(recorder) -> bool:\n    uri = getattr(recorder, 'artifact_uri', None)\n    if not uri or not uri.startswith('file:'):\n        return False\n    return os.path.isdir(str(Path(uri[len('file:'):]).parent.resolve()))","tryCatchPattern":"try:\n    path = rec.local_dir()\nexcept RuntimeError:\n    path = None  # remote artifact store: fall back to load_object()/list_artifacts()\nexcept ValueError:\n    raise  # run never started properly; caller must start the recorder first","preventionTips":["Prefer recorder.load_object()/list_artifacts over local_dir(); they work with any artifact store","Configure artifact_location to a shared local path (file://...) when experiments are created, if direct file access is needed","Mount the artifact root on every machine that reads the run; print rec.artifact_uri when debugging"],"tags":["qlib","mlflow","artifacts","filesystem","environment"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}