microsoft/qlib · error · NotImplementedError

Please implement the `create_recorder` method.

Error message

Please implement the `create_recorder` method.

What it means

Experiment.create_recorder is an abstract stub; it must return a Recorder object and is only implemented in subclasses like MLflowExperiment. The NotImplementedError means the running object is the base Experiment (or a subclass missing this method), so recorder creation cannot proceed.

Source

Thrown at qlib/workflow/exp.py:87

        recorder_status : str
            the status the recorder to be set with when ending (SCHEDULED, RUNNING, FINISHED, FAILED).
        """
        raise NotImplementedError(f"Please implement the `end` method.")

    def create_recorder(self, recorder_name=None):
        """
        Create a recorder for each experiment.

        Parameters
        ----------
        recorder_name : str
            the name of the recorder to be created.

        Returns
        -------
        A recorder object.
        """
        raise NotImplementedError(f"Please implement the `create_recorder` method.")

    def search_records(self, **kwargs):
        """
        Get a pandas DataFrame of records that fit the search criteria of the experiment.
        Inputs are the search criteria user want to apply.

        Returns
        -------
        A pandas.DataFrame of records, where each metric, parameter, and tag
        are expanded into their own columns named metrics.*, params.*, and tags.*
        respectively. For records that don't have a particular metric, parameter, or tag, their
        value will be (NumPy) Nan, None, or None respectively.
        """
        raise NotImplementedError(f"Please implement the `search_records` method.")

    def delete_recorder(self, recorder_id):
        """
        Create a recorder for each experiment.

View on GitHub (pinned to 79633dd950)

Solutions

  1. Rely on MLflowExperiment (default via qlib.init) which creates MLflowRecorder instances.
  2. Implement create_recorder(self, recorder_name=None) in your subclass to construct and return your Recorder type.
  3. If you only need retrieval, call _get_recorder/get_recorder with create=False instead of create_recorder.

Example fix

# before
rec = Experiment('1', 'e').create_recorder('r')  # NotImplementedError

# after
from qlib.workflow.exp import MLflowExperiment
rec = MLflowExperiment('1', 'e', uri='file:./mlruns').create_recorder('r')
Defensive patterns

Strategy: type-guard

Validate before calling

from qlib.workflow.exp import Experiment
assert exp.__class__.create_recorder is not Experiment.create_recorder

Type guard

def can_create_recorders(exp) -> bool:
    from qlib.workflow.exp import Experiment
    return exp.__class__.create_recorder is not Experiment.create_recorder

Prevention

When it happens

Trigger: Calling exp.create_recorder('name') on a directly instantiated Experiment; a custom Experiment backend that implements get_recorder but not create_recorder; unit tests instantiating the base class to probe the API.

Common situations: Developing a custom tracking backend and missing the factory method; using get_recorder(create=True) with a partially implemented subclass, which internally relies on recorder creation.

Related errors


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