microsoft/qlib · error · NotImplementedError
Please implement `save_obj`
Error message
Please implement `save_obj`
What it means
ObjManager is an abstract storage interface for named pickled objects; save_obj(obj, name) is the single-object write primitive and the base implementation intentionally raises NotImplementedError. Only concrete subclasses (FileManager, or user-provided managers) implement persistence. Reaching this line means you are calling save on the abstract base or an incomplete subclass.
Source
Thrown at qlib/utils/objm.py:24
from pathlib import Path
from qlib.config import C
from qlib.utils.pickle_utils import restricted_pickle_load
class ObjManager:
def save_obj(self, obj: object, name: str):
"""
save obj as name
Parameters
----------
obj : object
object to be saved
name : str
name of the object
"""
raise NotImplementedError(f"Please implement `save_obj`")
def save_objs(self, obj_name_l):
"""
save objects
Parameters
----------
obj_name_l : list of <obj, name>
"""
raise NotImplementedError(f"Please implement the `save_objs` method")
def load_obj(self, name: str) -> object:
"""
load object by name
Parameters
----------
name : strView on GitHub (pinned to 79633dd950)
Solutions
- Use qlib.utils.FileManager (file-backed implementation) instead of ObjManager for default persistence.
- If subclassing, implement save_obj(self, obj, name) so it persists `obj` under `name` in your backend.
- Add a compile-time guard: declare ObjManager as abc.ABC-style in your subclass and run static checks (mypy) to catch missing overrides.
Example fix
// before mgr = ObjManager() mgr.save_obj(model, 'model_v1') # NotImplementedError // after from qlib.utils import FileManager mgr = FileManager(path='./objs') mgr.save_obj(model, 'model_v1')
Defensive patterns
Strategy: type-guard
Validate before calling
from qlib.utils.objm import ObjManager, FileManager mgr = FileManager(path='./objs') if path else ObjManager() # prefer concrete impl
Type guard
def is_concrete_manager(mgr) -> bool:
return type(mgr).save_obj is not ObjManager.save_obj Try / catch
try:
mgr.save_obj(obj, name)
except NotImplementedError:
mgr = FileManager(path='./objs')
mgr.save_obj(obj, name) Prevention
- Default to FileManager; treat ObjManager purely as an interface.
- When subclassing, add an abstract-method check (inspect or mypy) that every ObjManager method is overridden.
When it happens
Trigger: ObjManager().save_obj(obj, 'name'), or a custom subclass that overrides save_objs but not save_obj; also mocking/partial-initializing a manager (e.g. with unittest.mock.patch) that leaves methods abstract.
Common situations: Building a custom remote/DB-backed object manager and forgetting one method; passing a bare ObjManager where qlib expects a FileManager (e.g. in qlib's workflow/task persistence); version upgrades that added new abstract methods to the interface.
Related errors
- Please implement the `save_objs` method
- Please implement the `load_obj` method
- Please implement the `exists` method
- Please implement the `list` method
- Please implement the `remove` method
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/d21fc5366b13d308.
Report an issue: GitHub.