{"record":{"id":"f9d859e615234fb4","repo":"apache/beam","slug":"cannot-call-read-after-iterating","errorCode":null,"errorMessage":"Cannot call read after iterating.","messagePattern":"Cannot call read after iterating\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/dataframe/io.py","lineNumber":552,"sourceCode":"    line_start = 0\n    chunk = self._read()\n    while True:\n      line_end = chunk.find(self._splitter._delim, line_start)\n      while line_end == -1:\n        more = self._read()\n        if not more:\n          if line_start < len(chunk):\n            yield chunk[line_start:]\n          return\n        chunk = chunk[line_start:] + more\n        line_start = 0\n        line_end = chunk.find(self._splitter._delim, line_start)\n      yield chunk[line_start:line_end + 1]\n      line_start = line_end + 1\n\n  def read(self, size=-1):\n    if self._iterator:\n      raise NotImplementedError('Cannot call read after iterating.')\n    return self._read(size)\n\n  def _read(self, size=-1):\n    if self._header:\n      res = self._header\n      self._header = None\n      return res\n    elif self._done:\n      return self._empty\n    elif size == -1:\n      self._buffer += self._underlying.read()\n    elif not self._buffer:\n      self._buffer = self._underlying.read(size)\n\n    if not self._buffer:\n      self._tracker.try_claim(self._tracker.current_restriction().stop)\n      self._done = True\n      return self._empty","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/dataframe/io.py#L534-L570","documentation":"The file-like wrapper around splittable reads permits either sequential reads or iteration, but not both; calling read() after iteration has begun raises NotImplementedError because the buffer position semantics cannot be guaranteed.","triggerScenarios":"Mixing access modes on the handle returned by the source, e.g. iterating the file object (for line in f) and then calling f.read(size), or a library helper that reads a header then falls back to .read().","commonSituations":"Custom code that peeks via iteration then reads the remainder; third-party parsing utilities assuming full file-like semantics.","solutions":["Choose one access mode: iterate fully or use read()/readline() consistently.","Re-open the file object if you need to restart reading from the beginning.","Use _read/readline API surface only, avoiding iteration, when mixing is required."],"exampleFix":"// before\nfor line in f:\n    break\ndata = f.read(1024)  # raises\n// after\ndata = f.read(1024)\nfor line in io.StringIO(data.decode()):\n    ...","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    data = handle.read(size)\nexcept NotImplementedError:\n    handle = reopen()  # fresh file object for read-after-iterate\n    data = handle.read(size)","preventionTips":["Pick one access mode per file handle: read OR iterate","Re-open handles instead of mixing modes","Wrap file-like handles before passing to third-party parsers that iterate"],"tags":["python","apache-beam","io","file-handle"],"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-14T16:17:12.679Z"}