apache/beam · critical · IllegalArgumentException
Cannot call #run(Pipeline) on an instance of
Error message
Cannot call #run(Pipeline) on an instance of %s. %s should only be used as the default to construct a Pipeline using %s, and cannot execute Pipelines. Instead, specify a %s by providing PipelineOptions in the system property '%s'.
What it means
CrashingRunner is Beam's default PipelineRunner that exists only to fail fast: any attempt to actually run a Pipeline throws this IllegalArgumentException. It indicates that no real runner (DirectRunner, FlinkRunner, DataflowRunner, ...) was configured, so PipelineOptions still carries the default CrashingRunner.
Solutions
- Set a real runner via PipelineOptions, e.g. `--runner=DirectRunner` or System property `-Drunner=DirectRunner`
- In code: `PipelineOptions opts = PipelineOptionsFactory.fromArgs(args).create(); opts.setRunner(DirectRunner.class);`
- If the pipeline is only meant for graph construction, do not call run(); use Pipeline.apply/merge only or GraphSurgeon-style tools
Example fix
// before
Pipeline p = Pipeline.create(PipelineOptionsFactory.create());
p.run();
// after
PipelineOptions opts = PipelineOptionsFactory.fromArgs("--runner=DirectRunner").create();
Pipeline p = Pipeline.create(opts);
p.run().waitUntilFinish(); Defensive patterns
Strategy: validation
Validate before calling
if (PipelineOptionsFactory.create().getRunner().equals(CrashingRunner.class)) {
throw new IllegalStateException("No real runner configured; pass --runner=<Runner> or -Drunner=");
} Type guard
boolean hasRealRunner(PipelineOptions opts) {
return opts.getRunner() != null && !CrashingRunner.class.equals(opts.getRunner());
} Try / catch
try {
pipeline.run().waitUntilFinish();
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("CrashingRunner")) {
throw new IllegalStateException("Configure a real runner, e.g. --runner=DirectRunner", e);
}
throw e;
} Prevention
- Always pass --runner=<DirectRunner|DataflowRunner|...> in args, system properties, or set options.setRunner(...) programmatically
- Never leave CrashingRunner as the runner in executable pipelines; it is only a safe default for construction-only usage
- Add a unit test asserting PipelineOptionsFactory.create().getRunner() != CrashingRunner.class in launch scripts
When it happens
Trigger: Calling Pipeline.run() (which delegates to CrashingRunner.run) without setting a real runner — i.e. no `--runner=` option and no `PipelineOptionsFactory`-registered runner; or explicitly instantiating CrashingRunner and calling run(Pipeline).
Common situations: Running a Beam job from an IDE or test harness without passing the `runner` system property; building a pipeline for serialization/inspection only and forgetting to swap in a real runner before execution; CI environments missing the runner option.
Related errors
- A schema was provided without a data format (or viceversa)…
- Batch size is too large! It should be smaller or equal than
- boolean cross product parameter required to explode more…
- Both a BigQuery table and a query were specified. Please…
- Both deidentification_template_name and…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/7639f719253cabaa.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/testing/CrashingRunner.java:38
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.PipelineResult;
import org.apache.beam.sdk.PipelineRunner;
import org.apache.beam.sdk.options.PipelineOptions;
/**
* A {@link PipelineRunner} that applies no overrides and throws an exception on calls to {@link
* Pipeline#run()}. For use in {@link TestPipeline} to construct but not execute pipelines.
*/
public final class CrashingRunner extends PipelineRunner<PipelineResult> {
@SuppressWarnings("unused") // used by reflection
public static CrashingRunner fromOptions(PipelineOptions opts) {
return new CrashingRunner();
}
@Override
public PipelineResult run(Pipeline pipeline) {
throw new IllegalArgumentException(
String.format(
"Cannot call #run(Pipeline) on an instance "
+ "of %s. %s should only be used as the default to construct a Pipeline "
+ "using %s, and cannot execute Pipelines. Instead, specify a %s "
+ "by providing PipelineOptions in the system property '%s'.",
CrashingRunner.class.getSimpleName(),
CrashingRunner.class.getSimpleName(),
TestPipeline.class.getSimpleName(),
PipelineRunner.class.getSimpleName(),
TestPipeline.PROPERTY_BEAM_TEST_PIPELINE_OPTIONS));
}
}
View on GitHub (pinned to 12126d8942)