apache/beam · error · IllegalArgumentException

must either have a non-empty list of PCollections, or must f

Error message

must either have a non-empty list of PCollections, or must first call empty(Pipeline)

What it means

PCollectionList.of(Iterable) requires at least one PCollection. An empty iterable cannot determine the owning Pipeline, so the constructor path throws IllegalArgumentException telling the caller to use PCollectionList.empty(pipeline) instead.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/values/PCollectionList.java:97

  public static <T> PCollectionList<T> of(PCollection<T> pc) {
    return new PCollectionList<T>(pc.getPipeline()).and(pc);
  }

  /**
   * Returns a {@link PCollectionList} containing the given {@link PCollection PCollections}, in
   * order.
   *
   * <p>The argument list cannot be empty.
   *
   * <p>All the {@link PCollection PCollections} in the resulting {@link PCollectionList} must be
   * part of the same {@link Pipeline}.
   *
   * <p>Longer PCollectionLists can be created by calling {@link #and} on the result.
   */
  public static <T> PCollectionList<T> of(Iterable<PCollection<T>> pcs) {
    Iterator<PCollection<T>> pcsIter = pcs.iterator();
    if (!pcsIter.hasNext()) {
      throw new IllegalArgumentException(
          "must either have a non-empty list of PCollections, "
              + "or must first call empty(Pipeline)");
    }
    return new PCollectionList<T>(pcsIter.next().getPipeline()).and(pcs);
  }

  /**
   * Returns a new {@link PCollectionList} that has all the {@link PCollection PCollections} of this
   * {@link PCollectionList} plus the given {@link PCollection} appended to the end.
   *
   * <p>All the {@link PCollection PCollections} in the resulting {@link PCollectionList} must be
   * part of the same {@link Pipeline}.
   */
  public PCollectionList<T> and(PCollection<T> pc) {
    if (pc.getPipeline() != pipeline) {
      throw new IllegalArgumentException("PCollections come from different Pipelines");
    }
    return new PCollectionList<>(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure the iterable passed to of() contains at least one PCollection
  2. Use PCollectionList.empty(pipeline) when you intentionally have no PCollections, then add with and(...)
  3. Check the collection with iterator().hasNext() or isEmpty() before calling of()

Example fix

// before
PCollectionList<T> list = PCollectionList.of(maybeEmpty); // throws when empty
// after
PCollectionList<T> list = maybeEmpty.iterator().hasNext()
    ? PCollectionList.of(maybeEmpty)
    : PCollectionList.empty(pipeline);
Defensive patterns

Strategy: validation

Validate before calling

if (pcs == null || !pcs.iterator().hasNext()) { return PCollectionList.empty(pipeline); }

Type guard

boolean nonEmpty(List<PCollection<T>> pcs) { return pcs != null && !pcs.isEmpty(); }

Try / catch

try { return PCollectionList.of(pcs); } catch (IllegalArgumentException e) { return PCollectionList.empty(pipeline); }

Prevention

When it happens

Trigger: Calling PCollectionList.of(Collections.emptyList()) or of an iterable filtered down to zero PCollections.

Common situations: Dynamically building a list of inputs where all candidate PCollections were filtered out; refactoring from PCollectionList.empty to of without ensuring non-emptiness.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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