apache/beam · error · IllegalArgumentException

Unsupported input type: {input.getClass()}

Error message

Unsupported input type: {input.getClass()}

What it means

Managed.resolveInput accepts either a PCollection or a PCollectionRowTuple and normalizes it into a PCollectionRowTuple. If the object passed to the managed transform's inputTuple/resolveInput is neither type, it throws this IllegalArgumentException naming the actual class. The managed API has no way to adapt that input shape.

Source

Thrown at sdks/java/managed/src/main/java/org/apache/beam/sdk/managed/Managed.java:271

    @VisibleForTesting
    static PCollectionRowTuple resolveInput(PInput input) {
      if (input instanceof PBegin) {
        return PCollectionRowTuple.empty(input.getPipeline());
      } else if (input instanceof PCollection) {
        PCollection<?> inputCollection = (PCollection<?>) input;
        Preconditions.checkArgument(
            inputCollection.getCoder() instanceof RowCoder,
            "Input PCollection must contain Row elements with a set Schema "
                + "(using .setRowSchema()). Instead, found collection %s with coder: %s.",
            inputCollection.getName(),
            inputCollection.getCoder());
        return PCollectionRowTuple.of(INPUT, (PCollection<Row>) inputCollection);
      } else if (input instanceof PCollectionRowTuple) {
        return (PCollectionRowTuple) input;
      }

      throw new IllegalArgumentException("Unsupported input type: " + input.getClass());
    }
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Convert the input to PCollection<Row> with a schema (setSchema / Row.withSchema) before applying the managed transform.
  2. If using a raw PCollection<Row>, simply pass it directly — it is supported.
  3. Use PCollectionRowTuple.of(Managed.INPUT, rowCollection) when composing multiple inputs.
  4. Check the managed transform's documentation for the required input type (Row-based).

Example fix

// before
pipeline.apply(Managed.write(Managed.SQLSERVER, config)).applyEvent(myStringPc);
// after
PCollection<Row> rows = myStringPc.apply(...parse...).apply(Rows.of(schema));
myStringPc.apply(Managed.write(Managed.SQLSERVER, config)); // applied to rows
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(input instanceof PCollection || input instanceof PCollectionRowTuple)) {
  throw new IllegalArgumentException("Managed input must be PCollection<Row> or PCollectionRowTuple, got " + input.getClass());
}

Type guard

boolean isManagedInput(Object in) { return (in instanceof PCollection<?> pc && pc.getSchema() != null) || in instanceof PCollectionRowTuple; }

Try / catch

try { return pipeline.apply(Managed.read(Managed.ICEBERG, config)); } catch (IllegalArgumentException e) { throw new IllegalStateException("Check managed input type", e); }

Prevention

When it happens

Trigger: Applying a Managed transform (e.g. Managed.SQLSERVER, Managed.KAFKA) to an input that is not a PCollection<Row> or PCollectionRowTuple, e.g. a raw PCollection<String>, PCollection<KV>, or some other PTransform-style input.

Common situations: Developers coming from other Beam connectors pass a differently-typed PCollection (e.g. strings or JSON objects) directly into a managed sink/source expecting auto-conversion.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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