microsoft/qlib · error · NotImplementedError

Please implement the `start_run` method.

Error message

Please implement the `start_run` method.

What it means

Recorder.start_run is the abstract method that begins (or resumes) a tracking run and returns an active-run context manager (mlflow.ActiveRun for the MLflow backend). The base class raises NotImplementedError; the error means start_run was called on the abstract Recorder — the MLflowRecorder override was not in play because the instance is the base class or an incomplete custom subclass.

Source

Thrown at qlib/workflow/recorder.py:114

        name : str
            name of the file to be loaded.

        Returns
        -------
        The saved object.
        """
        raise NotImplementedError(f"Please implement the `load_object` method.")

    def start_run(self):
        """
        Start running or resuming the Recorder. The return value can be used as a context manager within a `with` block;
        otherwise, you must call end_run() to terminate the current run. (See `ActiveRun` class in mlflow)

        Returns
        -------
        An active running object (e.g. mlflow.ActiveRun object).
        """
        raise NotImplementedError(f"Please implement the `start_run` method.")

    def end_run(self):
        """
        End an active Recorder.
        """
        raise NotImplementedError(f"Please implement the `end_run` method.")

    def log_params(self, **kwargs):
        """
        Log a batch of params for the current run.

        Parameters
        ----------
        keyword arguments
            key, value pair to be logged as parameters.
        """
        raise NotImplementedError(f"Please implement the `log_params` method.")

View on GitHub (pinned to 79633dd950)

Solutions

  1. Drive runs through QlibRecorder/R.start(experiment_name=...), which creates and starts an MLflowRecorder for you
  2. Implement start_run(self) in a custom Recorder subclass, returning a context-manager active-run object, and also implement end_run and the other abstract methods
  3. Verify which recorder class you actually hold: type(recorder) should be MLflowRecorder (or your subclass), never the bare Recorder

Example fix

# before
rec = Recorder(...)
with rec.start_run():   # NotImplementedError
    ...

# after
from qlib.workflow import R
with R.start(experiment_name='my_exp'):
    rec = R.get_recorder()
    ...
Defensive patterns

Strategy: type-guard

Validate before calling

from qlib.workflow.recorder import Recorder

def assert_startable(rec):
    if type(rec).start_run is Recorder.start_run:
        raise TypeError(f'{type(rec).__name__} does not implement start_run')

Type guard

from qlib.workflow.recorder import Recorder

def can_start_run(rec) -> bool:
    return type(rec).start_run is not Recorder.start_run

Try / catch

try:
    with rec.start_run():
        ...
except NotImplementedError as e:
    raise TypeError('use R.start(...) which drives a concrete MLflowRecorder') from e

Prevention

When it happens

Trigger: Directly instantiating qlib.workflow.recorder.Recorder and calling start_run; a custom Recorder subclass registered with QlibRecorder that lacks start_run; the workflow trying to use the default (abstract) recorder because no concrete recorder was created for the tracking URI scheme.

Common situations: Extending qlib with a non-MLflow tracker; misconfiguring QlibRecorder so it keeps the abstract default; calling low-level recorder APIs while bypassing R.start.

Related errors


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