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
- Drive runs through QlibRecorder/R.start(experiment_name=...), which creates and starts an MLflowRecorder for you
- 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
- 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
- Start runs with R.start(experiment_name=...); it handles recorder creation and start_run
- Do not bypass QlibRecorder to poke low-level recorder lifecycle methods
- Register custom recorder subclasses only after implementing the full abstract surface
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
- Please implement the `create_recorder` method.
- Please implement the `delete_recorder` method.
- Please implement the `_get_recorder` method
- Please implement the `list_recorders` method.
- Please implement the `save_objects` method.
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/97edcaec472e4fb2.
Report an issue: GitHub.