{"record":{"id":"dcc67a142cc6e9d9","repo":"apache/beam","slug":"runner-does-not-support-draining","errorCode":null,"errorMessage":"Runner does not support draining.","messagePattern":"Runner does not support draining\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/PipelineResult.java","lineNumber":56,"sourceCode":"  /**\n   * Cancels the pipeline execution.\n   *\n   * @throws IOException if there is a problem executing the cancel request.\n   * @throws UnsupportedOperationException if the runner does not support cancellation.\n   */\n  State cancel() throws IOException;\n\n  /**\n   * Drains the pipeline execution.\n   *\n   * <p>Draining requests that the runner stop accepting new input and finish processing data that\n   * has already entered the pipeline.\n   *\n   * @throws IOException if there is a problem executing the drain request.\n   * @throws UnsupportedOperationException if the runner does not support draining.\n   */\n  default State drain() throws IOException {\n    throw new UnsupportedOperationException(\"Runner does not support draining.\");\n  }\n\n  /**\n   * Waits until the pipeline finishes and returns the final status. It times out after the given\n   * duration.\n   *\n   * @param duration The time to wait for the pipeline to finish. Provide a value less than 1 ms for\n   *     an infinite wait.\n   * @return The final state of the pipeline or null on timeout.\n   * @throws UnsupportedOperationException if the runner does not support waiting to finish with a\n   *     timeout.\n   */\n  State waitUntilFinish(Duration duration);\n\n  /**\n   * Waits until the pipeline finishes and returns the final status.\n   *\n   * @return The final state of the pipeline.","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/PipelineResult.java#L38-L74","documentation":"PipelineResult.drain() is an optional API for draining (finishing without processing further input) a streaming pipeline. The default implementation in the PipelineResult interface throws UnsupportedOperationException because not every runner supports draining; the runner you are using never overrode it.","triggerScenarios":"Calling drain() on a PipelineResult from a runner that has not implemented it (e.g. DirectRunner or other runners without drain support).","commonSituations":"Code written for a streaming runner with drain support (like DataflowRunner/FlinkRunner in streaming mode) is run against a different runner (DirectRunner, TestPipeline) without checking support; batch pipelines where drain is meaningless.","solutions":["Check runner support before draining: if (result instanceof DrainingResult) or consult the runner's capabilities documentation.","Guard with try-catch on UnsupportedOperationException and fall back to cancel() or waitUntilFinish().","Switch to a runner that supports drain (e.g. run in streaming mode on Dataflow/Flink/Spark runners).","If the pipeline is batch, drain is not applicable - use cancel() or waitUntilFinish() instead."],"exampleFix":"// before\nPipelineResult result = pipeline.run();\nresult.drain();\n// after\nPipelineResult result = pipeline.run();\ntry {\n  result.drain();\n} catch (UnsupportedOperationException e) {\n  result.cancel(); // runner does not support draining\n}","handlingStrategy":"try-catch","validationCode":"// before draining, check capability\nif (result.getClass().getName().equals(\"org.apache.beam.sdk.runners.DirectRunner$DirectPipelineResult\")) {\n  throw new IllegalStateException(\"Runner does not support drain\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  result.drain();\n} catch (UnsupportedOperationException e) {\n  LOG.warn(\"Runner does not support draining; falling back to cancel\", e);\n  result.cancel();\n}","preventionTips":["Consult the runner capability matrix before relying on drain()","Abstract drain/cancel behind your own interface with per-runner implementations","Test streaming lifecycle code with the actual production runner, not just DirectRunner"],"tags":["java","apache-beam","runner","streaming","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}