apache/beam · error · UnsupportedOperationException

Unable to parse the output type

Error message

Unable to parse the output type ${output.getClass()} due to key ${entry.getKey()} not mapping to a PCollection

What it means

extractOutputs expects a transform's POutput to expand into values that are all PCollections. When some TupleTag maps to a non-PCollection PValue, the provider cannot expose it as a named output and throws, naming the output type and offending key.

Solutions

  1. Change the transform so its POutput contains only PCollections per TupleTag.
  2. Expose auxiliary values as additional PCollections rather than raw PValues.
  3. Wrap the transform to extract only its PCollection outputs before registering.
  4. Register an expansion-compatible variant of the transform.

Example fix

// before
outputMap.put(tag, (PValue) pCollectionView);
// after
outputMap.put(tag, resultingPCollection);
Defensive patterns

Strategy: type-guard

Validate before calling

Map<TupleTag<?>, PValue> vals = output.expand();
vals.forEach((tag, v) -> { if (!(v instanceof PCollection)) throw new IllegalArgumentException("Output " + tag + " is not a PCollection"); });

Type guard

boolean hasOnlyPCollections(POutput out) { return out.expand().values().stream().allMatch(v -> v instanceof PCollection); }

Try / catch

try { Map<String, PCollection<?>> outs = provider.extractOutputs(output); } catch (UnsupportedOperationException e) { log.error("Unsupported output: {}", e.getMessage()); throw new TransformContractException(e); }

Prevention

When it happens

Trigger: Using a custom POutput/transform whose expand() returns non-PCollection PValues (e.g. PCollectionViews or side artifacts) as expansion-service transform output.

Common situations: Custom transforms returning views or side inputs as outputs; wrappers not designed for cross-language expansion.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/TransformProvider.java:110

      return ((PCollectionTuple) output)
          .getAll().entrySet().stream()
              .collect(Collectors.toMap(entry -> entry.getKey().getId(), Map.Entry::getValue));
    } else if (output instanceof PCollectionList<?>) {
      PCollectionList<?> listOutput = (PCollectionList<?>) output;
      ImmutableMap.Builder<String, PCollection<?>> indexToPCollection = ImmutableMap.builder();
      int i = 0;
      for (PCollection<?> pc : listOutput.getAll()) {
        indexToPCollection.put(Integer.toString(i), pc);
        i++;
      }
      return indexToPCollection.build();
    } else if (output != null) {
      // This is needed to support custom output types.
      Map<TupleTag<?>, PValue> values = output.expand();
      Map<String, PCollection<?>> returnMap = new HashMap<>();
      for (Map.Entry<TupleTag<?>, PValue> entry : values.entrySet()) {
        if (!(entry.getValue() instanceof PCollection)) {
          throw new UnsupportedOperationException(
              "Unable to parse the output type "
                  + output.getClass()
                  + " due to key "
                  + entry.getKey()
                  + " not mapping to a PCollection");
        }
        returnMap.put(entry.getKey().getId(), (PCollection<?>) entry.getValue());
      }
      return returnMap;
    } else {
      throw new UnsupportedOperationException("Unknown output type: " + output.getClass());
    }
  }

  default Map<String, PCollection<?>> apply(
      Pipeline p, String name, RunnerApi.FunctionSpec spec, Map<String, PCollection<?>> inputs) {
    return extractOutputs(
        Pipeline.applyTransform(name, createInput(p, inputs), getTransform(spec, p.getOptions())));

View on GitHub (pinned to 12126d8942)