microsoft/qlib · error · NotImplementedError
Subclass of FeatureStorage must implement `start_index` meth
Error message
Subclass of FeatureStorage must implement `start_index` method
What it means
FeatureStorage.start_index (qlib/data/storage/storage.py:280) is an abstract property meant to return the left (inclusive) index of the stored data range, or None if the storage is empty. The base class raises NotImplementedError to force concrete backends (FileFeatureStorage, etc.) to define how the first data index is located. Reading `.start_index` on the base class or an incomplete subclass triggers this error.
Source
Thrown at qlib/data/storage/storage.py:280
@property
def data(self) -> pd.Series:
"""get all data
Notes
------
if data(storage) does not exist, return empty pd.Series: `return pd.Series(dtype=np.float32)`
"""
raise NotImplementedError("Subclass of FeatureStorage must implement `data` method")
@property
def start_index(self) -> Union[int, None]:
"""get FeatureStorage start index
Notes
-----
If the data(storage) does not exist, return None
"""
raise NotImplementedError("Subclass of FeatureStorage must implement `start_index` method")
@property
def end_index(self) -> Union[int, None]:
"""get FeatureStorage end index
Notes
-----
The right index of the data range (both sides are closed)
The next data appending point will be `end_index + 1`
If the data(storage) does not exist, return None
"""
raise NotImplementedError("Subclass of FeatureStorage must implement `end_index` method")
def clear(self) -> None:
raise NotImplementedError("Subclass of FeatureStorage must implement `clear` method")
View on GitHub (pinned to 79633dd950)
Solutions
- Use a concrete backend like FileFeatureStorage rather than the abstract base
- Implement `start_index` in your subclass: return the first index of the stored data, or None if storage does not exist
- Ensure any custom storage registered via the storage factory fully implements the FeatureStorage interface (data, start_index, end_index, clear, write)
- Audit isinstance checks so abstract instances are rejected before use
Example fix
// before
class MyStorage(FeatureStorage):
@property
def data(self):
return pd.Series(...)
# start_index not overridden -> NotImplementedError
// after
class MyStorage(FeatureStorage):
@property
def data(self):
return pd.Series(...)
@property
def start_index(self):
return None if len(self.data) == 0 else int(self.data.index[0]) Defensive patterns
Strategy: type-guard
Validate before calling
from qlib.data.storage.storage import FeatureStorage assert type(storage).start_index is not FeatureStorage.start_index, 'start_index not implemented'
Type guard
def has_concrete_start_index(storage) -> bool:
return type(storage).start_index is not FeatureStorage.start_index Try / catch
try:
si = storage.start_index
except NotImplementedError as e:
raise TypeError(f'{type(storage).__name__} lacks start_index implementation') from e Prevention
- Treat FeatureStorage as an interface; never instantiate the base class
- Add abstract-interface conformance tests for custom storage backends
When it happens
Trigger: Accessing `.start_index` on a directly instantiated FeatureStorage; implementing a custom storage backend without overriding the `start_index` property; code paths (e.g. rebase, calendar alignment) that query the range of a storage object that is actually the abstract base.
Common situations: Developing a custom storage backend and only implementing `data`/`write`; refactoring storage code so a factory accidentally returns the base class; testing with a mock that does not subclass correctly.
Related errors
- Subclass of FeatureStorage must implement `end_index` method
- Subclass of FeatureStorage must implement `data` method
- Subclass of FeatureStorage must implement `clear` method
- Subclass of FeatureStorage must implement `write` method
- Please implement the `get_all_stock` method
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/2b54196045445a4b.
Report an issue: GitHub.