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

  1. 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
  2. Check MLFLOW_TRACKING_URI / uri parameter of QlibRecorder matches the backend where the experiment was created (qlib.init or exp_manager uri)
  3. If the experiment was deleted, restore it (mlflow client.restore_experiment) or create a new one with R.set_uri/get_exp(create=True)
  4. 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

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


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/ec8082716b1fae2c. Report an issue: GitHub.