apache/beam · error · IllegalArgumentException

No Op handler has no output. This implies this IO is misconf

Error message

No Op handler has no output. This implies this IO is misconfigured.

What it means

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.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/errorhandling/ErrorHandler.java:234

   * without effects. This enables more simple codepaths without checking for whether the user
   * configured an error handler or not.
   */
  @Internal
  class DefaultErrorHandler<ErrorT, OutputT extends POutput>
      implements ErrorHandler<ErrorT, OutputT> {

    @Override
    public void addErrorCollection(PCollection<ErrorT> errorCollection) {}

    @Override
    public boolean isClosed() {
      throw new IllegalArgumentException(
          "No Op handler should not be closed. This implies this IO is misconfigured.");
    }

    @Override
    public @Nullable OutputT getOutput() {
      throw new IllegalArgumentException(
          "No Op handler has no output. This implies this IO is misconfigured.");
    }

    @Override
    public void close() {
      throw new IllegalArgumentException(
          "No Op handler should not be closed. This implies this IO is misconfigured.");
    }
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Configure a real error handler so a valid output exists.
  2. Make the IO conditionally fetch output only when error handling is enabled.
  3. Update downstream code not to consume the error output when using the No-Op handler.

Example fix

// before
PCollection<BadRecord> errors = errorHandler.getOutput(); // NoOp throws
// after
PCollection<BadRecord> errors =
    useErrorHandling ? errorHandler.getOutput() : null;
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(errorHandler instanceof ErrorHandler.NoOpErrorHandler)) { out = errorHandler.getOutput(); }

Type guard

boolean hasOutput(ErrorHandler<?> h) {
  return !(h instanceof ErrorHandler.NoOpErrorHandler);
}

Try / catch

try {
  out = errorHandler.getOutput();
} catch (IllegalArgumentException e) {
  throw new IllegalStateException("Error handling not configured for this IO", e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/29d1ce7f610525ab. Report an issue: GitHub.