microsoft/qlib · error · ValueError
No valid experiment has been found, please make sure the inp
Error message
No valid experiment has been found, please make sure the input experiment name is correct.
What it means
Raised by ExpManager when resolving an experiment by name fails: either MLflow's get_experiment_by_name returned None (no experiment with that name), the experiment's lifecycle_stage is DELETED, or the MLflow client itself raised MlflowException. The original MLflow error is chained as __cause__. It means the experiment name given to get_exp(experiment_name=...) cannot be mapped to a live MLflow experiment at the configured tracking URI.
Source
Thrown at qlib/workflow/expm.py:394
# https://www.mlflow.org/docs/latest/python_api/mlflow.tracking.html#mlflow.tracking.MlflowClient.get_experiment
exp = self.client.get_experiment(experiment_id)
if exp.lifecycle_stage.upper() == "DELETED":
raise MlflowException("No valid experiment has been found.")
experiment = MLflowExperiment(exp.experiment_id, exp.name, self.uri)
return experiment
except MlflowException as e:
raise ValueError(
"No valid experiment has been found, please make sure the input experiment id is correct."
) from e
elif experiment_name is not None:
try:
exp = self.client.get_experiment_by_name(experiment_name)
if exp is None or exp.lifecycle_stage.upper() == "DELETED":
raise MlflowException("No valid experiment has been found.")
experiment = MLflowExperiment(exp.experiment_id, experiment_name, self.uri)
return experiment
except MlflowException as e:
raise ValueError(
"No valid experiment has been found, please make sure the input experiment name is correct."
) from e
def search_records(self, experiment_ids=None, **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")
return self.client.search_runs(experiment_ids, filter_string, run_view_type, max_results, order_by)
def delete_exp(self, experiment_id=None, experiment_name=None):
assert (
experiment_id is not None or experiment_name is not None
), "Please input a valid experiment id or name before deleting."
try:
if experiment_id is not None:
self.client.delete_experiment(experiment_id)
else:View on GitHub (pinned to 79633dd950)
Solutions
- Verify the experiment exists at the tracking URI you are actually using: compare `R.get_exp(experiment_name=...)` input against `R.list_experiments()` output and fix the typo
- Check MLFLOW_TRACKING_URI / uri parameter of QlibRecorder matches the backend where the experiment was created (qlib.init or exp_manager uri)
- If the experiment was deleted, restore it (mlflow client.restore_experiment) or create a new one with R.set_uri/get_exp(create=True)
- Catch ValueError and inspect e.__cause__ (the original MlflowException) for backend-level failures such as connectivity or auth
Example fix
# before
exp = R.get_exp(experiment_name='alpha158') # ValueError: no valid experiment
# after
exp_names = [name for name in R.list_experiments()]
assert 'alpha158' in exp_names, f'pick from {exp_names}'
exp = R.get_exp(experiment_name='alpha158') Defensive patterns
Strategy: validation
Validate before calling
from qlib.workflow import R
def get_exp_safe(name: str):
exps = R.list_experiments() # {name: exp-like} of ACTIVE_ONLY experiments
if name not in exps:
raise KeyError(f'{name!r} not in active experiments: {sorted(exps)}')
return R.get_exp(experiment_name=name) Try / catch
try:
exp = R.get_exp(experiment_name=name)
except ValueError as e:
cause = e.__cause__ # original MlflowException, check for backend errors
if isinstance(cause, MlflowException) and 'RESOURCE_DOES_NOT_EXIST' in str(cause):
exp = R.get_exp(experiment_name=name, create=True)
else:
raise Prevention
- Always resolve experiment names from R.list_experiments() instead of typing them
- Set the tracking uri explicitly via qlib.init(...) or R.set_uri before any get_exp
- In reusable scripts, prefer get_exp(experiment_name=..., create=True) when creating-on-miss is acceptable
When it happens
Trigger: Calling exp_manager.get_exp(experiment_name='foo') (directly or via R.start with a non-existent experiment name); passing the name of an experiment that was deleted (lifecycle_stage == 'DELETED'); MLFLOW_TRACKING_URI pointing at a different backend than where the experiment lives; mlflow client raising MlflowException during lookup (e.g. backend unreachable, permission error).
Common situations: Typo in the 'experiment_name' field of a Qlib workflow config; switching tracking URI (local ./mlruns vs http server) so previously created experiments are not visible; re-running a notebook after the experiment was deleted via delete_exp or the mlflow UI; mlflow version differences in get_experiment_by_name behavior.
Related errors
- Error: {e}. Something went wrong when deleting experiment. P
- method {method} is not supported!
- This type of input {rtype} is not supported
- Can't find the BASE_CONFIG file: {base_config_path}
- Invalid Qlib configuration (note: the global config has alre
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/ec8082716b1fae2c.
Report an issue: GitHub.