{"record":{"id":"05daf2155d56255f","repo":"apache/beam","slug":"trying-to-iterate-through-a-cleared-listbuffer","errorCode":null,"errorMessage":"Trying to iterate through a cleared ListBuffer.","messagePattern":"Trying to iterate through a cleared ListBuffer\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/portability/fn_api_runner/execution.py","lineNumber":170,"sourceCode":"    else:\n      if not self._grouped_output:\n        output_stream_list = [create_OutputStream() for _ in range(n)]\n        idx = 0\n        for input in self._inputs:\n          input_stream = create_InputStream(input)\n          while input_stream.size() > 0:\n            decoded_value = self._coder_impl.decode_from_stream(\n                input_stream, True)\n            self._coder_impl.encode_to_stream(\n                decoded_value, output_stream_list[idx], True)\n            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,","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/portability/fn_api_runner/execution.py#L152-L188","documentation":"ListBuffer.__iter__ raises RuntimeError if the buffer has been cleared. Iterating a cleared buffer would yield nothing but usually indicates a lifecycle bug (data was already released), so it fails fast instead of silently returning empty results.","triggerScenarios":"Iterating (for x in buffer, list(buffer), etc.) a ListBuffer after clear() was called — e.g. reading buffered elements after bundle teardown or from a stale reference.","commonSituations":"Holding a reference to a buffer across clear() and reading it later; runner code consuming buffers in a different order than clear/partition; debugging code inspecting buffers post-clear.","solutions":["Copy the buffer contents (list(buffer)) before calling clear().","Iterate before clearing; reorder code so consumption precedes cleanup.","Call reset() if the buffer was intentionally cleared for reuse and should be repopulated first."],"exampleFix":"# before\nitems = list(buf)  # after buf.clear() -> RuntimeError\n# after\nitems = list(buf)\nbuf.clear()","handlingStrategy":"type-guard","validationCode":"if not buffer.cleared:\n    items = list(buffer)","typeGuard":"def is_readable(buf):\n    return not buf.cleared","tryCatchPattern":"try:\n    items = list(buffer)\nexcept RuntimeError:\n    items = []  # buffer was already cleared","preventionTips":["Snapshot contents (list(buf)) before clearing.","Consume buffers before teardown runs.","Avoid holding buffer references across clear() boundaries."],"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"}