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 name is correct.

What it means

MLflowExperiment._get_recorder resolves by name by scanning list_recorders() for the first (latest, since MLflow sorts by start_time DESC) run whose name matches; if none matches, this ValueError is raised. Note recorder names are not unique in MLflow, so only the latest match is ever returned.

Source

Thrown at qlib/workflow/exp.py:315

        ), "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")

        return self._client.search_runs([self.id], filter_string, run_view_type, max_results, order_by)

    def delete_recorder(self, recorder_id=None, recorder_name=None):
        assert (
            recorder_id is not None or recorder_name is not None
        ), "Please input a valid recorder id or name before deleting."
        try:
            if recorder_id is not None:
                self._client.delete_run(recorder_id)
            else:
                recorder = self._get_recorder(recorder_name=recorder_name)

View on GitHub (pinned to 79633dd950)

Solutions

  1. List actual names first: {r.name for r in exp.list_recorders().values()} and use an exact string.
  2. Prefer recorder_id for unambiguous retrieval; names only give the latest match.
  3. Confirm you are in the right experiment (R.get_exp) before the name lookup.

Example fix

# before
rec = exp.get_recorder(recorder_name='lit_gbm')  # ValueError

# after
names = {r.name: rid for rid, r in exp.list_recorders().items()}
rec = exp.get_recorder(recorder_id=names['lgb_model'])  # exact id lookup
Defensive patterns

Strategy: validation

Validate before calling

name2rid = {r.name: rid for rid, r in exp.list_recorders().items()}
if recorder_name not in name2rid:
    raise KeyError(f'no recorder named {recorder_name!r}; names: {sorted(set(name2rid))}')
rec = exp.get_recorder(recorder_id=name2rid[recorder_name])

Type guard

def recorder_name_exists(exp, name: str) -> bool:
    return any(r.name == name for r in exp.list_recorders().values())

Try / catch

try:
    rec = exp.get_recorder(recorder_name=name)
except ValueError:
    rec = exp.get_recorder(recorder_id=latest_rid)  # fallback to id-based retrieval

Prevention

When it happens

Trigger: exp.get_recorder(recorder_name='nnmodel') when no run in this experiment is named 'nnmodel'; name differs by case/spacing ('NNModel' vs 'nnmodel'); the matching run lives in a different experiment; a name given where an id was expected.

Common situations: Assuming the recorder_name equals the experiment name or the model class; renaming recorders in code but querying with old names; multiple experiments each with similarly named runs and querying the wrong one.

Related errors


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