{"record":{"id":"0a1f323980bac0d0","repo":"apache/beam","slug":"cannot-access-the-output-of-an-error-handler-until-it-has","errorCode":null,"errorMessage":"Cannot access the output of an error handler until it has been closed.","messagePattern":"Cannot access the output of an error handler until it has been closed\\.","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/error_handling.py","lineNumber":82,"sourceCode":"  def __exit__(self, *exec_info):\n    if exec_info[0] is None:\n      self.close()\n\n  def close(self):\n    \"\"\"Indicates all error-producing operations have reported any errors.\n\n    Invokes the provided error consuming PTransform on any provided error\n    PCollections.\n    \"\"\"\n    self._output = (\n        tuple(self._error_pcolls) | transforms.Flatten() | self._consumer)\n    self._closed = True\n\n  def output(self):\n    \"\"\"Returns result of applying the error consumer to the error pcollections.\n    \"\"\"\n    if not self._closed:\n      raise RuntimeError(\n          \"Cannot access the output of an error handler \"\n          \"until it has been closed.\")\n    return self._output\n\n  def add_error_pcollection(self, pcoll):\n    \"\"\"Called by a class implementing error handling on the error records.\n    \"\"\"\n    pcoll.pipeline._register_error_handler(self)\n    self._error_pcolls.append(pcoll)\n\n  def verify_closed(self):\n    \"\"\"Called at end of pipeline construction to ensure errors are not ignored.\n    \"\"\"\n    if not self._closed:\n      raise RuntimeError(\n          \"Unclosed error handler initialized at %s\" % self._creation_traceback)\n\n","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/error_handling.py#L64-L100","documentation":"ErrorHandler.output() returns the transformed error PCollections produced by applying the error consumer, but only after the handler has been 'closed' (its consumer can no longer be attached to more transforms). Apache Beam throws this RuntimeError because accessing the output before close() would expose PCollections that are not yet wired into the pipeline.","triggerScenarios":"Calling handler.output() in a pipeline-construction block before the with_exception_handling(...) context manager exits (which sets _closed=True).","commonSituations":"Developers grabbing the collected error records mid-pipeline-construction, or hoisting output() out of the with-block to inspect results before Beam finalizes the handler.","solutions":["Move the handler.output() call inside (or after) the with error_handling(...) block so close() has run first.","Ensure every ErrorHandler created is used as a context manager; do not call output() manually right after construction.","If you need error records, write them to a sink or read them after pipeline completion instead of accessing output() early."],"exampleFix":"# before\nhandler = ErrorHandlingConfig(...)\nresult = handler.output()  # RuntimeError\n# after\nwith error_handling(...) as handler:\n  transformed = pcoll.with_exception_handling(...)\n  result = handler.output()  # valid: handler closed on exit","handlingStrategy":"try-catch","validationCode":"if not getattr(handler, '_closed', False):\n    raise RuntimeError('call handler.output() only after the with-block closes it')","typeGuard":"def output_ready(handler) -> bool:\n    return bool(getattr(handler, '_closed', False))","tryCatchPattern":"try:\n    out = handler.output()\nexcept RuntimeError:\n    # handler not yet closed; finish pipeline construction first\n    out = None","preventionTips":["Always use error handlers as context managers (with ... as handler:).","Only read handler.output() inside or after the with-block.","Never hoist output() out of pipeline construction code."],"tags":["python","apache-beam","pipeline-construction","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-14T16:17:12.679Z"}