microsoft/qlib · error · ValueError
No valid recorder has been found, please make sure the input
Error message
No valid recorder has been found, please make sure the input recorder id is correct.
What it means
Raised by MLflowExperiment._get_recorder when MlflowClient.get_run(recorder_id) throws MlflowException (run not found, deleted, or malformed id); the MLflow error is chained into this ValueError. It means the id simply does not correspond to a run inside this experiment's tracking store.
Source
Thrown at qlib/workflow/exp.py:304
def _get_recorder(self, recorder_id=None, recorder_name=None):
"""
Method for getting or creating a recorder. It will try to first get a valid recorder, if exception occurs, it will
raise errors.
Quoting docs of search_runs from MLflow
> The default ordering is to sort by start_time DESC, then run_id.
"""
assert (
recorder_id is not None or recorder_name is not None
), "Please input at least one of recorder id or name before retrieving recorder."
if recorder_id is not None:
try:
run = self._client.get_run(recorder_id)
recorder = MLflowRecorder(self.id, self._uri, mlflow_run=run)
return recorder
except MlflowException as mlflow_exp:
raise ValueError(
"No valid recorder has been found, please make sure the input recorder id is correct."
) from mlflow_exp
elif recorder_name is not None:
logger.warning(
f"Please make sure the recorder name {recorder_name} is unique, we will only return the latest recorder if there exist several matched the given name."
)
recorders = self.list_recorders()
for rid in recorders:
if recorders[rid].name == recorder_name:
return recorders[rid]
raise ValueError("No valid recorder has been found, please make sure the input recorder name is correct.")
def search_records(self, **kwargs):
filter_string = "" if kwargs.get("filter_string") is None else kwargs.get("filter_string")
run_view_type = 1 if kwargs.get("run_view_type") is None else kwargs.get("run_view_type")
max_results = 100000 if kwargs.get("max_results") is None else kwargs.get("max_results")
order_by = kwargs.get("order_by")
View on GitHub (pinned to 79633dd950)
Solutions
- Verify the recorder exists first: exp.list_recorders() and confirm the id-keyed dict contains it.
- Make sure the tracking URI matches where the run was created (check R.get_uri() / C.exp_manager['kwargs']['uri']).
- Strip/normalize the id and confirm it is a 32-hex MLflow run_id, not an experiment_id or recorder name.
- If the run was deleted, restore it in MLflow or accept it is gone.
Example fix
# before rec = exp.get_recorder(recorder_id='abc123') # ValueError: no valid recorder # after rids = exp.list_recorders() # dict keyed by run_id rec = exp.get_recorder(recorder_id=next(iter(rids))) # use a verified id
Defensive patterns
Strategy: validation
Validate before calling
rids = exp.list_recorders() # dict keyed by run_id
if recorder_id not in rids:
raise KeyError(f'{recorder_id} not in experiment {exp.id}; available: {list(rids)[:5]}')
rec = exp.get_recorder(recorder_id=recorder_id) Type guard
def recorder_id_exists(exp, rid: str) -> bool:
return rid in exp.list_recorders() Try / catch
try:
rec = exp.get_recorder(recorder_id=rid)
except ValueError as e:
if 'recorder id is correct' in str(e):
rid = next(iter(exp.list_recorders())) # recover with a known id
rec = exp.get_recorder(recorder_id=rid)
else:
raise Prevention
- Always fetch recorder ids from list_recorders()/save_recorder() return values, never hand-typed.
- Pin the tracking URI before any id-based lookup so ids come from the same store.
- Store the recorder id returned by start_exp immediately for later use.
When it happens
Trigger: exp.get_recorder(recorder_id='<bad-or-deleted-run-id>'); recorder_id copied from a different tracking URI / mlruns directory; run was soft-deleted via delete_run before retrieval; id has trailing whitespace or wrong case.
Common situations: Switching exp_manager uri between runs (file:./mlruns vs file:./another_mlruns) so ids from the old store are looked up in the new one; resuming old experiments whose artifacts were cleaned; typos when pasting run ids into R.get_recorder.
Related errors
- No valid recorder has been found, please make sure the input
- Error: {e}. Something went wrong when deleting recorder. Ple
- No valid experiment has been found, please make sure the inp
- Please make sure the recorder has been created and started p
- This type of input {rtype} is not supported
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/cef9439c5e8a776b.
Report an issue: GitHub.