{"record":{"id":"b2a01fbcd2e230fa","repo":"apache/beam","slug":"stream-is-closed","errorCode":null,"errorMessage":"Stream is closed.","messagePattern":"Stream is closed\\.","errorType":"exception","errorClass":"IOError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/filesystemio.py","lineNumber":305,"sourceCode":"    # Certain upload stream implementations seek to the end of a stream to check\n    # length before completing an upload, so we support a no-op seek(0, SEEK_END).\n    if whence == os.SEEK_END and offset == 0:\n      return\n    elif whence == os.SEEK_SET:\n      if offset == self.position:\n        return\n      elif offset == self.last_block_position and self.last_block:\n        self.position = offset\n        self.remaining = b''.join([self.last_block, self.remaining])\n        self.last_block = b''\n        return\n    raise NotImplementedError(\n        'offset: %s, whence: %s, position: %s, last: %s' %\n        (offset, whence, self.position, self.last_block_position))\n\n  def _check_open(self):\n    if self.closed:\n      raise IOError('Stream is closed.')\n","sourceCodeStart":287,"sourceCodeEnd":306,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/filesystemio.py#L287-L306","documentation":"_check_open() raises IOError('Stream is closed.') when any operation (tell, seek, read, readline, etc.) is attempted on a FilesystemIO stream whose closed flag is set. Once close() has been called the stream no longer fronts a valid downloader/reader, so every subsequent operation is rejected.","triggerScenarios":"Calling f.tell(), f.seek(...), or f.read(...) after f.close(); using a stream inside a `with` block after the block has exited; holding a reference to a stream whose underlying context manager closed it.","commonSituations":"Returning file-like objects from context managers and using them later; accidentally calling close() twice in cleanup code then reading again; iterator/generator code that outlives the `with FileSystems.open(...)` scope.","solutions":["Reopen the file with FileSystems.open(path) before performing further operations.","Track the closed state (f.closed) and guard read/tell calls, or keep the stream inside the `with` block that owns its lifetime.","Remove duplicate close() calls so the stream isn't closed while still in use.","Capture any data you need before the `with` block exits rather than deferring reads."],"exampleFix":"// before\nwith FileSystems.open(path) as f:\n    pass\npos = f.tell()  # IOError: Stream is closed.\n// after\nwith FileSystems.open(path) as f:\n    pos = f.tell()\n    data = f.read()","handlingStrategy":"validation","validationCode":"if f.closed:\n    f = FileSystems.open(path)  # reopen before further ops","typeGuard":"def is_open(f) -> bool:\n    return not getattr(f, 'closed', True)","tryCatchPattern":"try:\n    pos = f.tell()\nexcept IOError as e:\n    if str(e) == 'Stream is closed.':\n        f = FileSystems.open(path)\n        pos = f.tell()\n    else:\n        raise","preventionTips":["Perform all reads/tells inside the `with FileSystems.open(...)` block.","Check f.closed before any late/deferred access to a stream.","Never call close() twice; centralize cleanup in one place.","Don't return streams from context managers — return the data instead."],"tags":["python","io","closed-stream","lifecycle"],"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"}