{"record":{"id":"b280a01e99c8fe42","repo":"apache/beam","slug":"trying-to-partition-a-cleared-listbuffer","errorCode":null,"errorMessage":"Trying to partition a cleared ListBuffer.","messagePattern":"Trying to partition a cleared ListBuffer\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/portability/fn_api_runner/execution.py","lineNumber":149,"sourceCode":"\n  def extend(self, extra: 'Buffer') -> None:\n    if self.cleared:\n      raise RuntimeError('Trying to append to a cleared ListBuffer.')\n    if self._grouped_output:\n      raise RuntimeError('ListBuffer append after read.')\n    assert isinstance(extra, ListBuffer)\n    self._inputs.extend(extra._inputs)\n\n  def append(self, element: bytes) -> None:\n    if self.cleared:\n      raise RuntimeError('Trying to append to a cleared ListBuffer.')\n    if self._grouped_output:\n      raise RuntimeError('ListBuffer append after read.')\n    self._inputs.append(element)\n\n  def partition(self, n: int) -> list[list[bytes]]:\n    if self.cleared:\n      raise RuntimeError('Trying to partition a cleared ListBuffer.')\n    if len(self._inputs) >= n or len(self._inputs) == 0:\n      return [self._inputs[k::n] for k in range(n)]\n    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","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/portability/fn_api_runner/execution.py#L131-L167","documentation":"ListBuffer.partition() raises RuntimeError if the buffer was cleared. Partitioning a cleared buffer would operate on an empty/invalid _inputs list and break the buffer lifecycle contract, so it is rejected.","triggerScenarios":"Calling buffer.partition(n) after buffer.clear() — e.g. requesting partition slices of a reused buffer that was cleared but never reset().","commonSituations":"Runner-side code partitioning cached buffers between bundles without reset(); calling partition after teardown/cleanup already ran.","solutions":["Call reset() before partition() if reusing a cleared buffer.","Partition only buffers that are actively holding data for the current bundle.","Create a fresh ListBuffer instead of reusing cleared ones."],"exampleFix":"# before\nbuf.clear()\nparts = buf.partition(4)  # RuntimeError\n# after\nbuf.clear()\nbuf.reset()\nparts = buf.partition(4)","handlingStrategy":"type-guard","validationCode":"if buffer.cleared:\n    buffer.reset()\nparts = buffer.partition(n)","typeGuard":"def is_partitionable(buf):\n    return not buf.cleared","tryCatchPattern":"try:\n    parts = buffer.partition(n)\nexcept RuntimeError:\n    buffer.reset()\n    parts = buffer.partition(n)","preventionTips":["Partition only buffers actively holding current-bundle data.","Reset cleared buffers before reuse.","Avoid partitioning after cleanup/teardown code ran."],"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"}