microsoft/qlib · error · NotImplementedError

Please implement the `start` method.

Error message

Please implement the `start` method.

What it means

qlib's Experiment is an abstract base class; start() only exists as a stub that raises NotImplementedError. The concrete implementation lives in MLflowExperiment (qlib/workflow/exp.py) and any user-defined subclass. Hitting this means the abstract Experiment.start() was called instead of an overridden implementation, i.e. the object is a bare/incomplete Experiment, not a configured tracking backend.

Source

Thrown at qlib/workflow/exp.py:61

    def start(self, *, recorder_id=None, recorder_name=None, resume=False):
        """
        Start the experiment and set it to be active. This method will also start a new recorder.

        Parameters
        ----------
        recorder_id : str
            the id of the recorder to be created.
        recorder_name : str
            the name of the recorder to be created.
        resume : bool
            whether to resume the first recorder

        Returns
        -------
        An active recorder.
        """
        raise NotImplementedError(f"Please implement the `start` method.")

    def end(self, recorder_status=Recorder.STATUS_S):
        """
        End the experiment.

        Parameters
        ----------
        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
        ----------

View on GitHub (pinned to 79633dd950)

Solutions

  1. Do not instantiate Experiment directly; use the default MLflowExperiment via qlib.init() (C.exp_manager['class'] defaults to 'MLflowExpManager').
  2. If you subclass Experiment, implement start(self, recorder_id=None, recorder_name=None, resume=False) so it creates and activates a Recorder.
  3. Check for typos/signature drift in your override; the method must be named exactly 'start' on the subclass.
  4. Verify C['exp_manager']['class'] resolves to your fully implemented subclass before calling R.start_exp().

Example fix

# before
exp = Experiment(id='1', name='e')
exp.start()  # NotImplementedError

# after
from qlib.workflow.exp import MLflowExperiment
exp = MLflowExperiment(id='1', name='e', uri='file:./mlruns')
rec = exp.start()  # or implement start() in your own subclass
Defensive patterns

Strategy: type-guard

Validate before calling

from qlib.workflow.exp import Experiment, MLflowExperiment
exp = R.get_exp()
assert type(exp) is not Experiment, 'abstract Experiment in use; init qlib with MLflowExpManager'

Type guard

def is_concrete_experiment(exp) -> bool:
    return type(exp).__name__ != 'Experiment' and exp.__class__.start is not Experiment.start

Prevention

When it happens

Trigger: Directly instantiating Experiment(...) and calling .start(); calling R.start_exp()/exp.start() when C['exp_manager']['class'] was changed to a class that inherits Experiment but never overrides start(); a custom experiment class whose method name is misspelled (e.g. Start or strat).

Common situations: Writing a custom tracking backend (e.g. wrapping TensorBoard/W&B instead of MLflow) and forgetting to implement start; copy-pasting an experiment class from an older qlib version whose abstract surface grew; class-resolver config pointing at the base class itself.

Related errors


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