{"record":{"id":"29d1ce7f610525ab","repo":"apache/beam","slug":"no-op-handler-has-no-output-this-implies-this-io-is","errorCode":null,"errorMessage":"No Op handler has no output. This implies this IO is misconfigured.","messagePattern":"No Op handler has no output\\. This implies this IO is misconfigured\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/errorhandling/ErrorHandler.java","lineNumber":234,"sourceCode":"   * without effects. This enables more simple codepaths without checking for whether the user\n   * configured an error handler or not.\n   */\n  @Internal\n  class DefaultErrorHandler<ErrorT, OutputT extends POutput>\n      implements ErrorHandler<ErrorT, OutputT> {\n\n    @Override\n    public void addErrorCollection(PCollection<ErrorT> errorCollection) {}\n\n    @Override\n    public boolean isClosed() {\n      throw new IllegalArgumentException(\n          \"No Op handler should not be closed. This implies this IO is misconfigured.\");\n    }\n\n    @Override\n    public @Nullable OutputT getOutput() {\n      throw new IllegalArgumentException(\n          \"No Op handler has no output. This implies this IO is misconfigured.\");\n    }\n\n    @Override\n    public void close() {\n      throw new IllegalArgumentException(\n          \"No Op handler should not be closed. This implies this IO is misconfigured.\");\n    }\n  }\n}\n","sourceCodeStart":216,"sourceCodeEnd":245,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/errorhandling/ErrorHandler.java#L216-L245","documentation":"NoOpErrorHandler.getOutput always throws IllegalArgumentException: a No-Op handler never produces an error-sink output PCollection, so requesting one signals that an IO is treating the placeholder handler as a real handler. This is a deliberate fail-fast to expose misconfiguration.","triggerScenarios":"A translate()/expand() path calls getOutput() on ErrorHandler.getNoOpHandler() when the pipeline was configured without error handling but the IO unconditionally reads the handler's output.","commonSituations":"IOs that always fetch the error output regardless of whether error handling was enabled; user code switching a pipeline to no-error-handling while downstream code still consumes the error PCollection.","solutions":["Configure a real error handler so a valid output exists.","Make the IO conditionally fetch output only when error handling is enabled.","Update downstream code not to consume the error output when using the No-Op handler."],"exampleFix":"// before\nPCollection<BadRecord> errors = errorHandler.getOutput(); // NoOp throws\n// after\nPCollection<BadRecord> errors =\n    useErrorHandling ? errorHandler.getOutput() : null;","handlingStrategy":"type-guard","validationCode":"if (!(errorHandler instanceof ErrorHandler.NoOpErrorHandler)) { out = errorHandler.getOutput(); }","typeGuard":"boolean hasOutput(ErrorHandler<?> h) {\n  return !(h instanceof ErrorHandler.NoOpErrorHandler);\n}","tryCatchPattern":"try {\n  out = errorHandler.getOutput();\n} catch (IllegalArgumentException e) {\n  throw new IllegalStateException(\"Error handling not configured for this IO\", e);\n}","preventionTips":["Enable a real error handler when consuming error output PCollections","Gate output consumption on whether error handling was enabled","Avoid unconditional getOutput() in generic IO translation code"],"tags":["java","apache-beam","error-handling","no-op-handler","misconfiguration"],"backgroundTag":"invalid-config-value","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"}