microsoft/qlib · error · ValueError
Please make sure the recorder has been created and started p
Error message
Please make sure the recorder has been created and started properly before getting artifact uri.
What it means
Raised by Recorder.local_path when self.artifact_uri is None. The artifact URI is only populated after the recorder (an MLflow run) has been created and started; calling local_path on a recorder that was never started leaves artifact_uri None, so there is nothing to resolve into a local directory path.
Source
Thrown at qlib/workflow/recorder.py:331
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} ...")
# NOTE: making logging async.
# - This may cause delay when uploading results
# - The logging time may not be accurate
View on GitHub (pinned to 79633dd950)
Solutions
- Ensure the recorder is started before touching artifacts: use exp.get_recorder() only after R.start() and a successful run, or call recorder.start_run() first.
- Check recorder.artifact_uri is not None before calling local_path; if None, re-create the recorder via R.get_exp().create_recorder(...) + start_run().
- If the run was created through qlib.workflow.R, verify the MLflow tracking URI is reachable so start_run() actually persisted the run.
- If you truly have a valid run id, reload the recorder from the tracking store (e.g. MLflow client.get_run(id).info.artifact_uri) instead of using the un-started object.
Example fix
// before
recorder = exp.get_recorder()
path = recorder.local_path # ValueError if run never started
// after
recorder = exp.get_recorder()
if recorder.artifact_uri is None:
recorder.start_run()
path = recorder.local_path Defensive patterns
Strategy: validation
Validate before calling
if recorder.artifact_uri is None:
raise RuntimeError(f"Recorder {recorder.id} not started; artifact_uri is None")
path = recorder.local_path Try / catch
try:
path = recorder.local_path
except ValueError as e:
if "artifact uri" in str(e):
recorder.start_run()
path = recorder.local_path
else:
raise Prevention
- Always obtain recorders via R.get_recorder() after a completed run, not from a fresh experiment object.
- Assert recorder.artifact_uri is not None before any artifact/local-path access.
- Confirm the MLflow tracking server is reachable before starting workflows.
When it happens
Trigger: Calling recorder.local_path (directly or via APIs that save/read artifacts locally) on a Recorder instance obtained before start_run()/create_recorder was committed, e.g. R.get_recorder() on a fresh experiment where the run failed to start, or a Recorder constructed manually without starting.
Common situations: Experiment was created but the recorder start threw earlier (e.g. MLflow tracking server unreachable), user reuses a stale Recorder object after the run crashed, or the tracking backend is remote (the sibling RuntimeError branch also fires when the artifact dir is not local).
Related errors
- 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
- This type of input is not supported
- The type of dataset is not DatasetH instead of {:}
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/d0e16d4a7dfa8365.
Report an issue: GitHub.