microsoft/qlib · error · RuntimeError
This recorder is not saved in the local file system.
Error message
This recorder is not saved in the local file system.
What it means
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'.
Source
Thrown at qlib/workflow/recorder.py:328
@property
def artifact_uri(self):
return self._artifact_uri
def get_local_dir(self):
"""
This function will return the directory path of this recorder.
"""
if self.artifact_uri is not None:
if platform.system() == "Windows":
local_dir_path = Path(self.artifact_uri.lstrip("file:").lstrip("/")).parent
else:
local_dir_path = Path(self.artifact_uri.lstrip("file:")).parent
local_dir_path = str(local_dir_path.resolve())
if os.path.isdir(local_dir_path):
return local_dir_path
else:
raise RuntimeError("This recorder is not saved in the local file system.")
else:
raise ValueError(
"Please make sure the recorder has been created and started properly before getting artifact uri."
)
def start_run(self):
# set the tracking uri
mlflow.set_tracking_uri(self.uri)
# start the run
run = mlflow.start_run(self.id, self.experiment_id, self.name)
# save the run id and artifact_uri
self.id = run.info.run_id
self._artifact_uri = run.info.artifact_uri
self.start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.status = Recorder.STATUS_R
logger.info(f"Recorder {self.id} starts running under Experiment {self.experiment_id} ...")
View on GitHub (pinned to 79633dd950)
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
Example fix
# before
# MLflow server with server-side artifacts
rec.local_dir() # RuntimeError: not saved in local file system
# after (option 1: local artifact root)
mlflow.create_experiment('my_exp', artifact_location='file:///mnt/shared/mlruns/my_exp')
# after (option 2: use artifact API instead of local path)
pred = rec.load_object('pred.pkl') Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
def local_dir_safe(recorder) -> str:
uri = recorder.artifact_uri
if uri is None:
raise ValueError('recorder not started; no artifact_uri')
if not uri.startswith('file:'):
raise RuntimeError(f'artifacts are remote ({uri}); local_dir() unsupported')
p = str(Path(uri[len('file:'):]).parent.resolve())
if not os.path.isdir(p):
raise RuntimeError(f'artifact path {p} missing; check mounts')
return p Type guard
import os
from pathlib import Path
def has_local_artifacts(recorder) -> bool:
uri = getattr(recorder, 'artifact_uri', None)
if not uri or not uri.startswith('file:'):
return False
return os.path.isdir(str(Path(uri[len('file:'):]).parent.resolve())) Try / catch
try:
path = rec.local_dir()
except RuntimeError:
path = None # remote artifact store: fall back to load_object()/list_artifacts()
except ValueError:
raise # run never started properly; caller must start the recorder first Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- User data for {} already exists
- Please implement the `search_records` method.
- No valid recorder has been found, please make sure the input
- No valid recorder has been found, please make sure the input
- Error: {e}. Something went wrong when deleting recorder. Ple
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/7570f28163b543fe.
Report an issue: GitHub.