apache/beam · error · UnsupportedOperationException
A %s cannot be expanded
Error message
A %s cannot be expanded
What it means
RunnerPCollectionView is a runner-side placeholder implementation of PCollectionView used during pipeline construction/translation. It carries only a coder and TupleTag and has no backing PTransform, so expand() unconditionally throws UnsupportedOperationException: 'A RunnerPCollectionView cannot be expanded'. PValues are normally expanded during pipeline construction; a runner view should never participate in that.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/RunnerPCollectionView.java:95
@Override
public WindowMappingFn<?> getWindowMappingFn() {
return windowMappingFn;
}
@Override
public WindowingStrategy<?, ?> getWindowingStrategyInternal() {
return windowingStrategy;
}
@Override
public Coder<?> getCoderInternal() {
return coder;
}
@Override
public Map<TupleTag<?>, PValue> expand() {
throw new UnsupportedOperationException(
String.format("A %s cannot be expanded", RunnerPCollectionView.class.getSimpleName()));
}
@Override
public boolean equals(@Nullable Object other) {
if (!(other instanceof PCollectionView)) {
return false;
}
@SuppressWarnings("unchecked")
PCollectionView<?> otherView = (PCollectionView<?>) other;
return tag.equals(otherView.getTagInternal());
}
@Override
public int hashCode() {
return Objects.hash(tag);
}
}View on GitHub (pinned to 12126d8942)
Solutions
- Do not call expand() on RunnerPCollectionView; keep a reference to the original user-side PCollectionView if expansion metadata is needed.
- When walking a pipeline graph, treat views as already-expanded leaves and skip them (check instanceof RunnerPCollectionView).
- Ensure side inputs passed to transforms come from the same Pipeline that is being built, not from a translated/runner representation.
Example fix
// before
for (PValue value : pCollection.expand()) { ... }
// after
if (!(view instanceof RunnerPCollectionView)) {
for (PValue value : view.expand()) { ... }
} Defensive patterns
Strategy: type-guard
Validate before calling
if (view instanceof RunnerPCollectionView) { skipExpansion(view); } Type guard
boolean isRunnerView(PValue v) { return v instanceof RunnerPCollectionView; } Try / catch
try { values = view.expand(); } catch (UnsupportedOperationException e) { /* runner view: treat as expanded leaf */ } Prevention
- Never call expand() on runner-side views
- Use original user-built PCollectionViews for metadata
- When walking pipelines, skip RunnerPCollectionView instances
When it happens
Trigger: Calling expand() (directly, or via PValue.expansion / getProducingTransformInternal / pipeline application logic) on a PCollectionView that is a RunnerPCollectionView — e.g. iterating over a pipeline's PValues and calling expand() on views obtained from a translated/runner-side context instead of the original user-built view.
Common situations: Custom runners or pipeline-manipulation code that walks PValues and calls expand(), passing runner-created views into APIs that expect construction-time views, or mixing views between two different Pipeline instances.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- TODO: Add support for reading the timestamp from the encoded
- Invalid secret type %s, currently supported types: %s
- Unsupported secret manager: '%s'. Currently supported option
- @WatermarkEstimatorState parameters are not supported.
- Unknown or unsupported WindowFn:
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/21da47a76b149a77.
Report an issue: GitHub.