microsoft/qlib · error · NotImplementedError
Please implement the `end_exp` method.
Error message
Please implement the `end_exp` method.
What it means
ExpManager.end_exp clears _active_exp_uri then delegates to _end_exp, an abstract hook whose base body raises NotImplementedError. It fires when the active manager is the base ExpManager or an incomplete subclass, i.e. no backend logic exists to end the experiment and finalize its recorder status.
Source
Thrown at qlib/workflow/expm.py:117
"""
End an active experiment.
Maintaining `_active_exp_uri` is included in end_exp, remaining implementation should be included in _end_exp in subclass
Parameters
----------
experiment_name : str
name of the active experiment.
recorder_status : str
the status of the active recorder of the experiment.
"""
self._active_exp_uri = None
# The subclass may set the underlying uri back.
# So setting `_active_exp_uri` come before `_end_exp`
self._end_exp(recorder_status=recorder_status, **kwargs)
def _end_exp(self, recorder_status: Text = Recorder.STATUS_S, **kwargs):
raise NotImplementedError(f"Please implement the `end_exp` method.")
def create_exp(self, experiment_name: Optional[Text] = None):
"""
Create an experiment.
Parameters
----------
experiment_name : str
the experiment name, which must be unique.
Returns
-------
An experiment object.
Raise
-----
ExpAlreadyExistError
"""View on GitHub (pinned to 79633dd950)
Solutions
- Use the default MLflowExpManager via qlib.init().
- Implement _end_exp(self, recorder_status=Recorder.STATUS_S, **kwargs) in your subclass to close the active experiment.
- Ensure the whole hook set (_start_exp, _end_exp, create_exp, _get_exp, delete_exp, list_experiments, search_records) is implemented.
Example fix
# before
class MyManager(ExpManager):
pass
R.end_exp() # NotImplementedError from base _end_exp
# after
class MyManager(ExpManager):
def _end_exp(self, recorder_status=Recorder.STATUS_S, **kwargs):
self.active_experiment.set_status(recorder_status) Defensive patterns
Strategy: type-guard
Validate before calling
from qlib.workflow.expm import ExpManager assert R.exp_manager.__class__._end_exp is not ExpManager._end_exp, '_end_exp not implemented'
Type guard
def manager_can_end(mgr) -> bool:
from qlib.workflow.expm import ExpManager
return mgr.__class__._end_exp is not ExpManager._end_exp Prevention
- Pair every _start_exp implementation with _end_exp in custom managers.
- Prefer R.end_exp() with the shipped MLflow manager.
When it happens
Trigger: R.end_exp() with a custom or bare exp_manager lacking _end_exp; calling end_exp after replacing the default MLflowExpManager in C['exp_manager'].
Common situations: Skeleton custom tracking managers that implement start but not end; test doubles subclassing ExpManager without full coverage of hooks.
Related errors
- Please implement the `start_exp` method.
- Please implement the `create_exp` method.
- Please implement the `search_records` method.
- Please implement the `_get_exp` method
- Please implement the `delete_exp` method.
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/1881353c2a009dbd.
Report an issue: GitHub.