microsoft/qlib · error · NotImplementedError
Please implement the `list_recorders` method.
Error message
Please implement the `list_recorders` method.
What it means
Experiment.list_recorders(rtype, **flt_kwargs) is an abstract method that must return either a dict (id -> Recorder) or a list of Recorder objects, optionally filtered (e.g. status=Recorder.STATUS_FI). The base stub raises NotImplementedError; MLflowExperiment implements it by listing runs via MlflowClient with a 50000-record cap.
Source
Thrown at qlib/workflow/exp.py:240
self, rtype: Literal["dict", "list"] = RT_D, **flt_kwargs
) -> Union[List[Recorder], Dict[str, Recorder]]:
"""
List all the existing recorders of this experiment. Please first get the experiment instance before calling this method.
If user want to use the method `R.list_recorders()`, please refer to the related API document in `QlibRecorder`.
flt_kwargs : dict
filter recorders by conditions
e.g. list_recorders(status=Recorder.STATUS_FI)
Returns
-------
The return type depends on `rtype`
if `rtype` == "dict":
A dictionary (id -> recorder) of recorder information that being stored.
elif `rtype` == "list":
A list of Recorder.
"""
raise NotImplementedError(f"Please implement the `list_recorders` method.")
class MLflowExperiment(Experiment):
"""
Use mlflow to implement Experiment.
"""
def __init__(self, id, name, uri):
super(MLflowExperiment, self).__init__(id, name)
self._uri = uri
self._default_rec_name = "mlflow_recorder"
self._client = mlflow.tracking.MlflowClient(tracking_uri=self._uri)
def __repr__(self):
return "{name}(id={id}, info={info})".format(name=self.__class__.__name__, id=self.id, info=self.info)
def start(self, *, recorder_id=None, recorder_name=None, resume=False):
logger.info(f"Experiment {self.id} starts running ...")
View on GitHub (pinned to 79633dd950)
Solutions
- Get the experiment from R.get_exp(...) so the MLflow implementation is used.
- Implement list_recorders in your subclass honoring rtype ('dict'/'list') and status filters.
- For large result sets, remember the MLflow implementation caps at UNLIMITED=50000 runs.
Example fix
# before
Experiment('1', 'e').list_recorders() # NotImplementedError
# after
exp = R.get_exp(experiment_name='alpha158')
recs = exp.list_recorders(status=Recorder.STATUS_FI) # dict of finished recorders Defensive patterns
Strategy: type-guard
Validate before calling
from qlib.workflow.exp import Experiment assert exp.__class__.list_recorders is not Experiment.list_recorders, 'listing unsupported'
Type guard
def listable(exp) -> bool:
from qlib.workflow.exp import Experiment
return exp.__class__.list_recorders is not Experiment.list_recorders Prevention
- Enumerate recorders via R.list_recorders with the default manager.
- Remember MLflow-backed listing caps at 50000 runs.
When it happens
Trigger: exp.list_recorders() on a directly instantiated Experiment; R.list_recorders(exp_name) delegating to a custom Experiment subclass that never overrode list_recorders.
Common situations: Custom backends implementing only run creation; analysis notebooks enumerating finished recorders; migrations where the subclass was written against an older interface.
Related errors
- Please implement the `create_recorder` method.
- Please implement the `delete_recorder` method.
- Please implement the `_get_recorder` method
- Please implement the `list_experiments` method.
- Please implement the `save_objects` method.
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/588084cc4e9e8e4d.
Report an issue: GitHub.