apache/beam · error · AbandonedNodeException
The pipeline contains abandoned PAssert(s).
Error message
The pipeline contains abandoned PAssert(s).
What it means
After a run, TestPipeline compares pipeline graph nodes against nodes actually visited during execution. If PAssert nodes exist that were never visited by the run, it throws AbandonedNodeException with this message — meaning some assertions were attached but never evaluated.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/testing/TestPipeline.java:237
return; // this method is to protect against spurious success, so failure is fine
}
final List<TransformHierarchy.Node> runVisitedNodes =
checkStateNotNull(
this.runVisitedNodes,
"Internal error: non-empty pipeline has been visited but still no runVisitedNodes");
final List<TransformHierarchy.Node> pipelineNodes = recordPipelineNodes(pipeline);
if (runVisitedNodes.equals(pipelineNodes)) {
return;
}
final boolean hasDanglingPAssert =
pipelineNodes.stream()
.filter(Predicates.not(Predicates.in(runVisitedNodes)))
.anyMatch(isPAssertNode);
if (hasDanglingPAssert) {
throw new AbandonedNodeException("The pipeline contains abandoned PAssert(s).");
} else {
throw new AbandonedNodeException("The pipeline contains abandoned PTransform(s).");
}
}
private boolean pipelineRunSucceeded() {
return runVisitedNodes != null;
}
@Override
protected void afterPipelineExecution() {
runVisitedNodes = recordPipelineNodes(pipeline);
super.afterPipelineExecution();
}
@Override
protected void afterUserCodeFinished() {
super.afterUserCodeFinished();View on GitHub (pinned to 12126d8942)
Solutions
- Add all PAssert.that(...) calls before invoking pipeline.run().
- Verify the PAssert is attached to a PCollection that is part of the executed pipeline (not a detached/unused output).
- Re-run the pipeline after adding new assertions.
Example fix
// before
pipeline.run().waitUntilFinish();
PAssert.that(pcoll).containsInAnyOrder("x");
// after
PAssert.that(pcoll).containsInAnyOrder("x");
pipeline.run().waitUntilFinish(); Defensive patterns
Strategy: validation
Validate before calling
boolean allAssertsBeforeRun = assertsAddedAt < runCalledAt; // enforce asserts precede run()
Try / catch
try { pipeline.run().waitUntilFinish(); } catch (AbandonedNodeException e) { fail("Attach PAsserts before run(): " + e.getMessage()); } Prevention
- Add every PAssert.that(...) before pipeline.run().
- Never mutate the pipeline after run().
- Assert on PCollections belonging to the executed pipeline graph only.
When it happens
Trigger: PAsserts added to the pipeline after run() was called, or PAsserts applied to a side branch that the runner never executed/visited, with runVisitedNodes not containing them.
Common situations: Conditionally adding assertions after run(); attaching PAsserts to outputs of transforms pruned by the runner; building a second pipeline object and asserting on it while running another.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- The pipeline has not been run.
- The pipeline contains abandoned PTransform(s).
- Not expected to access DoFn.StartBundleContext from @Process
- Not expected to access DoFn.FinishBundleContext from @Proces
- Cannot access key as parameter outside of @OnTimer method.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/4c4a9dc9a8d4829e.
Report an issue: GitHub.