apache/beam · error · RuntimeException

Unhandled input type ${input.getClass()}

Error message

Unhandled input type ${input.getClass()}

What it means

PythonExternalTransform.apply accepts only PCollection, PCollectionList, PCollectionTuple, PCollectionRowTuple, or PBegin as input. Any other PInput type cannot be wired to the underlying external Python transform, so the library throws RuntimeException naming the unhandled class. This is an internal exhaustiveness guard over supported input types.

Source

Thrown at sdks/java/extensions/python/src/main/java/org/apache/beam/sdk/extensions/python/PythonExternalTransform.java:595

      ExternalTransforms.ExternalConfigurationPayload payload) {
    PTransform<PInput, PCollectionTuple> transform =
        External.of(
                "beam:transforms:python:fully_qualified_named",
                payload.toByteArray(),
                expansionService)
            .withMultiOutputs()
            .withOutputCoder(this.outputCoders);
    PCollectionTuple outputs;
    if (input instanceof PCollection) {
      outputs = ((PCollection<?>) input).apply(transform);
    } else if (input instanceof PCollectionTuple) {
      outputs = ((PCollectionTuple) input).apply(transform);
    } else if (input instanceof PCollectionRowTuple) {
      outputs = ((PCollectionRowTuple) input).apply(transform);
    } else if (input instanceof PBegin) {
      outputs = ((PBegin) input).apply(transform);
    } else {
      throw new RuntimeException("Unhandled input type " + input.getClass());
    }
    Set<TupleTag<?>> tags = outputs.getAll().keySet();
    if (tags.size() == 1) {
      return (OutputT) outputs.get(Iterables.getOnlyElement(tags));
    } else {
      return (OutputT) outputs;
    }
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Convert the input to a supported type (PCollection, PCollectionList, PCollectionTuple, PCollectionRowTuple, or PBegin) before applying the transform
  2. If starting a pipeline, use pipeline.apply(...) with PBegin
  3. Check what concrete type your generic helper actually passes and narrow its signature

Example fix

// before
PCollection<String> out = ext.apply(mysteryInput); // RuntimeException
// after
PCollection<String> out = pipeline.apply(Create.of(...)).apply(ext);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(input instanceof PCollection || input instanceof PCollectionList
    || input instanceof PCollectionTuple || input instanceof PCollectionRowTuple
    || input instanceof PBegin)) {
  throw new IllegalArgumentException("Unsupported input type: " + input.getClass());
}

Type guard

boolean isSupportedInput(org.apache.beam.sdk.values.PInput in) {
  return in instanceof PCollection || in instanceof PCollectionList
      || in instanceof PCollectionTuple || in instanceof PCollectionRowTuple
      || in instanceof PBegin;
}

Try / catch

try {
  result = ext.apply(input);
} catch (RuntimeException e) {
  if (e.getMessage().startsWith("Unhandled input type")) {
    // convert input to a supported PInput type and retry
  }
}

Prevention

When it happens

Trigger: Calling apply/expand with a custom or unexpected PInput implementation — e.g. passing a PTransform input wrapper, a null-derived custom collection, or a type from another SDK surface not among the five handled cases.

Common situations: Generic pipeline helper methods typed as PInput that pass through arbitrary inputs; custom subclass of PCollection; refactoring that changes the input type without updating the transform application.

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/0dc270731297bf6c. Report an issue: GitHub.