apache/beam · error · IllegalStateException

Cannot call getFromRowFunction when there is no schema

Error message

Cannot call getFromRowFunction when there is no schema

What it means

PCollection.getFromRowFunction() throws this IllegalStateException when the PCollection lacks a schema. The Row -> T function only exists when the coder is a SchemaCoder; the method fails fast instead of returning null.

Solutions

  1. Guard with pc.hasSchema() before the call
  2. Attach a schema via pc.setSchema(schema, toRowFn, fromRowFn) so the fromRowFunction is available
  3. Register the element type with Beam's schema framework (annotated POJO/bean) so the coder is a SchemaCoder

Example fix

// before
SerializableFunction<Row, T> fn = pc.getFromRowFunction(); // throws
// after
if (!pc.hasSchema()) {
  pc = pc.setRowSchema(mySchema);
}
SerializableFunction<Row, T> fn = pc.getFromRowFunction();
Defensive patterns

Strategy: validation

Validate before calling

if (!pc.hasSchema()) { pc = pc.setRowSchema(mySchema); }

Type guard

boolean canDecodeFromRow(PCollection<?> pc) { return pc.hasSchema(); }

Try / catch

try { var fn = pc.getFromRowFunction(); } catch (IllegalStateException e) { pc = pc.setRowSchema(mySchema); }

Prevention

When it happens

Trigger: Calling getFromRowFunction() directly or via fromRowFunction() on a PCollection whose coder is not a SchemaCoder, e.g. before any setSchema call or on output of non-schema transforms.

Common situations: Decoding Rows back into typed objects in a DoFn without a registered schema; mixing Row-based IO connectors with plain-typed PCollections.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/values/PCollection.java:341

  public Schema getSchema() {
    if (!hasSchema()) {
      throw new IllegalStateException("Cannot call getSchema when there is no schema");
    }
    return ((SchemaCoder) getCoder()).getSchema();
  }

  /** Returns the attached schema's toRowFunction. */
  public SerializableFunction<T, Row> getToRowFunction() {
    if (!hasSchema()) {
      throw new IllegalStateException("Cannot call getToRowFunction when there is no schema");
    }
    return ((SchemaCoder<T>) getCoder()).getToRowFunction();
  }

  /** Returns the attached schema's fromRowFunction. */
  public SerializableFunction<Row, T> getFromRowFunction() {
    if (!hasSchema()) {
      throw new IllegalStateException("Cannot call getFromRowFunction when there is no schema");
    }
    return ((SchemaCoder<T>) getCoder()).getFromRowFunction();
  }

  /**
   * of the {@link PTransform}.
   *
   * @return the output of the applied {@link PTransform}
   */
  public <OutputT extends POutput> OutputT apply(PTransform<? super PCollection<T>, OutputT> t) {
    return Pipeline.applyTransform(this, t);
  }

  /**
   * Applies the given {@link PTransform} to this input {@link PCollection}, using {@code name} to
   * identify this specific application of the transform. This name is used in various places,
   * including the monitoring UI, logging, and to stably identify this application node in the job
   * graph.

View on GitHub (pinned to 12126d8942)