microsoft/qlib · error · KeyError
The segment is out of valid calendar
Error message
The segment is out of valid calendar
What it means
Raised as KeyError by CalendarProvider.shift when the shifted start index exceeds len(self.cals): after moving forward by step, the segment's start would fall past the last known trading day in the provider's calendar, so no valid dates can be returned.
Source
Thrown at qlib/workflow/task/utils.py:277
--------
tuple: new segment
Raises
------
KeyError:
shift will raise error if the index(both start and end) is out of self.cal
"""
if isinstance(seg, tuple):
start_idx, end_idx = self.align_idx(seg[0], tp_type="start"), self.align_idx(seg[1], tp_type="end")
if rtype == self.SHIFT_SD:
start_idx = self._add_step(start_idx, step)
end_idx = self._add_step(end_idx, step)
elif rtype == self.SHIFT_EX:
end_idx = self._add_step(end_idx, step)
else:
raise NotImplementedError(f"This type of input is not supported")
if start_idx is not None and start_idx > len(self.cals):
raise KeyError("The segment is out of valid calendar")
return self.get(start_idx), self.get(end_idx)
else:
raise NotImplementedError(f"This type of input is not supported")
def replace_task_handler_with_cache(task: dict, cache_dir: Union[str, Path] = ".") -> dict:
"""
Replace the handler in task with a cache handler.
It will automatically cache the file and save it in cache_dir.
>>> import qlib
>>> qlib.auto_init()
>>> import datetime
>>> # it is simplified task
>>> task = {"dataset": {"kwargs":{'handler': {'class': 'Alpha158', 'module_path': 'qlib.contrib.data.handler', 'kwargs': {'start_time': datetime.date(2008, 1, 1), 'end_time': datetime.date(2020, 8, 1), 'fit_start_time': datetime.date(2008, 1, 1), 'fit_end_time': datetime.date(2014, 12, 31), 'instruments': 'CSI300'}}}}}
>>> new_task = replace_task_handler_with_cache(task)
>>> print(new_task)
{'dataset': {'kwargs': {'handler': 'file...Alpha158.3584f5f8b4.pkl'}}}View on GitHub (pinned to 79633dd950)
Solutions
- Bound the number of rolling folds by (calendar_end_idx - train_start_idx) / step; stop rolling when shift would exceed the calendar.
- Update/extend the qlib calendar data (dump_bin / calendars directory) so it covers the full period you roll over.
- Catch KeyError and treat it as the natural stop condition of the rolling loop instead of a crash.
Example fix
// before
for i in range(100):
seg = cal.shift(seg, step=20) # KeyError on late folds
// after
for i in range(100):
try:
seg = cal.shift(seg, step=20)
except KeyError:
break # reached end of calendar Defensive patterns
Strategy: try-catch
Validate before calling
max_step = len(cal.cals) - cal.align_idx(seg[0], tp_type="start")
if step > max_step:
raise IndexError(f"shift step {step} exceeds calendar by {step - max_step}") Try / catch
try:
next_seg = cal.shift(seg, step)
except KeyError as e:
if "valid calendar" in str(e):
break # natural end of rolling folds
raise Prevention
- Compute the maximum feasible folds from calendar length before the rolling loop.
- Keep qlib calendar data up to date so the valid range matches your backtest horizon.
- Treat KeyError from shift as a loop terminator, not a crash.
When it happens
Trigger: Calling shift(seg, step) with a step large enough that seg[0] + step runs past the end of the calendar, typically when rolling a train segment forward over many folds until it exceeds the data range.
Common situations: Rolling retrain loops (RollingGen + TaskGen) where the number of folds × step overruns available history; using a short/too-recent calendar (e.g. missing updated calendars day.txt) so valid range is smaller than expected; expanding windows whose end was clamped earlier leaving inconsistent indices.
Related errors
- This type of input {rtype} is not supported
- This type of input is not supported
- astype not supported: {astype}
- The rolling window size of Skewness operation should >= 3
- The rolling window size of Kurtosis operation should >= 5
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/0fb835486974cc2a.
Report an issue: GitHub.