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

  1. Do not call expand() on RunnerPCollectionView; keep a reference to the original user-side PCollectionView if expansion metadata is needed.
  2. When walking a pipeline graph, treat views as already-expanded leaves and skip them (check instanceof RunnerPCollectionView).
  3. 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

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


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