{"record":{"id":"cdf56da33a1e1f07","repo":"apache/beam","slug":"trying-to-reset-a-non-cleared-listbuffer","errorCode":null,"errorMessage":"Trying to reset a non-cleared ListBuffer.","messagePattern":"Trying to reset a non-cleared ListBuffer\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/portability/fn_api_runner/execution.py","lineNumber":181,"sourceCode":"            idx = (idx + 1) % n\n        self._grouped_output = [[output_stream.get()]\n                                for output_stream in output_stream_list]\n      return self._grouped_output\n\n  def __iter__(self) -> Iterator[bytes]:\n    if self.cleared:\n      raise RuntimeError('Trying to iterate through a cleared ListBuffer.')\n    return iter(self._inputs)\n\n  def clear(self) -> None:\n    self.cleared = True\n    self._inputs = []\n    self._grouped_output = None\n\n  def reset(self) -> None:\n    \"\"\"Resets a cleared buffer for reuse.\"\"\"\n    if not self.cleared:\n      raise RuntimeError('Trying to reset a non-cleared ListBuffer.')\n    self.cleared = False\n\n\nclass GroupingBuffer(object):\n  \"\"\"Used to accumulate groupded (shuffled) results.\"\"\"\n  def __init__(\n      self,\n      pre_grouped_coder: coders.Coder,\n      post_grouped_coder: coders.Coder,\n      windowing: core.Windowing) -> None:\n    self._key_coder = pre_grouped_coder.key_coder()\n    self._pre_grouped_coder = pre_grouped_coder\n    self._post_grouped_coder = post_grouped_coder\n    self._table: collections.defaultdict[bytes,\n                                         list[Any]] = collections.defaultdict(\n                                             list)\n    self._windowing = windowing\n    self._grouped_output: Optional[list[list[bytes]]] = None","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/portability/fn_api_runner/execution.py#L163-L199","documentation":"ListBuffer.reset() is meant to revive a cleared buffer for reuse; it raises RuntimeError when called on a buffer that is not cleared. Resetting a live buffer would silently discard the lifecycle invariant (cleared flag toggling), so it is only allowed after clear().","triggerScenarios":"Calling buffer.reset() on a fresh or actively-used buffer (cleared is False), e.g. unconditionally calling reset() between bundles on a newly created buffer.","commonSituations":"Buffer-reuse pooling code that calls reset() defensively on every checkout, including brand-new buffers; double reset() calls after an earlier reset already flipped cleared to False.","solutions":["Only call reset() on buffers you previously clear()ed; check buffer.cleared first.","For new buffers, skip reset() entirely — they are already usable.","Track cleared state in the pool and only reset on checkout of a cleared buffer."],"exampleFix":"# before\nbuf.reset()  # fresh buffer -> RuntimeError\n# after\nif buf.cleared:\n  buf.reset()","handlingStrategy":"type-guard","validationCode":"if buffer.cleared:\n    buffer.reset()","typeGuard":"def needs_reset(buf):\n    return buf.cleared","tryCatchPattern":"try:\n    buffer.reset()\nexcept RuntimeError:\n    pass  # buffer was never cleared; nothing to reset","preventionTips":["Only reset buffers you previously cleared.","Skip reset() on freshly created buffers.","Track cleared state in buffer pools to reset only on checkout of cleared buffers."],"tags":["apache-beam","fn-api-runner","buffer-lifecycle","runtime-error"],"backgroundTag":"invalid-state-transition","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"}