{"record":{"id":"05ac5727582b9696","repo":"apache/beam","slug":"key-value-d-is-out-of-range","errorCode":null,"errorMessage":"key value %d is out of range","messagePattern":"key value (.+?) is out of range","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/worker/bundle_processor.py","lineNumber":780,"sourceCode":"      self,\n      state_handler: sdk_worker.CachingStateHandler,\n      state_key: beam_fn_api_pb2.StateKey,\n      value_coder: coders.Coder) -> None:\n    self._state_handler = state_handler\n    self._state_key = state_key\n    self._elem_coder = beam.coders.TupleCoder(\n        [coders.VarIntCoder(), coders.coders.LengthPrefixCoder(value_coder)])\n    self._cleared = False\n    self._pending_adds = SortedDict()\n    self._pending_removes = RangeSet()\n\n  def add(self, elem: tuple[timestamp.Timestamp, Any]) -> None:\n    assert len(elem) == 2\n    key_ts, value = elem\n    key = key_ts.micros\n\n    if key >= self.RANGE_MAX or key < self.RANGE_MIN:\n      raise ValueError(\"key value %d is out of range\" % key)\n    self._pending_adds.setdefault(key, []).append(value)\n\n  def read(self) -> Iterable[tuple[timestamp.Timestamp, Any]]:\n    return self.read_range(self.TIMESTAMP_RANGE_MIN, self.TIMESTAMP_RANGE_MAX)\n\n  def read_range(\n      self,\n      min_timestamp: timestamp.Timestamp,\n      limit_timestamp: timestamp.Timestamp\n  ) -> Iterable[tuple[timestamp.Timestamp, Any]]:\n    # convert timestamp to int, as sort keys are stored as int internally.\n    min_key = min_timestamp.micros\n    limit_key = limit_timestamp.micros\n\n    keys_to_add = self._pending_adds.irange(\n        min_key, limit_key, inclusive=(True, False))\n\n    # use list interpretation here to construct the actual list","sourceCodeStart":762,"sourceCodeEnd":798,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/worker/bundle_processor.py#L762-L798","documentation":"Timers in the worker are indexed by a timestamp in microseconds, and this map-like structure enforces a valid timestamp range (RANGE_MIN..RANGE_MAX, derived from the 8-byte key encoding). A TimerMap.add() with a timestamp micros value outside that range raises ValueError. It guards against timestamps that cannot round-trip through the backing store.","triggerScenarios":"Calling add() on the timer state map with a Timestamp whose .micros exceeds RANGE_MAX or is below RANGE_MIN — e.g. timer set at an extreme timestamp (far past/far future) like 9999-12-31 or negative epoch values.","commonSituations":"Setting timers at datetime.max/min sentinels; using windows with enormous allowed timestamps; negative timestamps from bad event-time parsing.","solutions":["Clamp the timer timestamp to the valid range before setting (e.g. cap at a safe max like 2262-04-11)","Use a realistic event-time timestamp instead of datetime.max/min sentinels","Adjust window/trigger logic so timers fire within representable range","Add a validation step that rejects out-of-range event times upstream"],"exampleFix":"// before\nTimerSpec.set_timer(w, 'cleanup', firing_time=datetime.max)\n// after\nmax_ts = datetime.datetime(2262, 4, 11)\nTimerSpec.set_timer(w, 'cleanup', firing_time=min(firing_time, max_ts))","handlingStrategy":"validation","validationCode":"import apache_beam.utils.timestamp as ts\nRANGE_MIN, RANGE_MAX = -9223372036854, 9223372036854  # per worker TimerMap bounds\ndef timer_ts_ok(dt):\n    micros = ts.Timestamp.from_rfc3339(dt.isoformat()).micros if hasattr(dt, 'isoformat') else int(dt) * 1_000_000\n    return RANGE_MIN <= micros < RANGE_MAX\n# call before set_timer; clamp firing_time otherwise","typeGuard":null,"tryCatchPattern":"try:\n    ctx.set_timer('cleanup', firing_time)\nexcept ValueError as e:\n    if 'key value' in str(e) and 'out of range' in str(e):\n        logging.warning('Timer timestamp %s out of range; clamping', firing_time)\n        ctx.set_timer('cleanup', min(max(firing_time, min_ts), max_ts))\n    else:\n        raise","preventionTips":["Never use datetime.max/min as timer timestamps; use clamped sentinels","Validate event times at pipeline entry (reject or clamp extremes)","Remember representable range roughly ±292,000 years in micros vs. practical window bounds","Add unit tests for timers at boundary timestamps"],"tags":["apache-beam","python","timer","timestamp-range"],"backgroundTag":"value-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}