apache/beam · error · java.lang.IllegalArgumentException

Could not determine the row function for class

Error message

Could not determine the row function for class 

What it means

For a constructor parameter whose value arrives as a Beam Row, the decoder looks up a fromRow function in the SchemaRegistry for the target class. If the class has no registered schema (NoSuchSchemaException), it throws IllegalArgumentException naming the class.

Solutions

  1. Annotate the class with @DefaultSchema(JavaBeanSchema.class) or another SchemaProvider.
  2. Explicitly register it: SchemaRegistry.getDefault().getSchemaProvider(MyClass.class) or register(Class, SchemaProvider).
  3. Make sure the same ClassLoader in the expansion service loads the annotated class.
  4. Catch IllegalArgumentException and surface 'register a schema for class X' guidance to the pipeline author.

Example fix

// before
public class MyOptions { private String name; ... }
// after
@DefaultSchema(JavaBeanSchema.class)
public class MyOptions { private String name; ... }
Defensive patterns

Strategy: validation

Validate before calling

try { SchemaRegistry.getDefault().getSchema(MyClass.class); } catch (NoSuchSchemaException e) { throw new IllegalStateException("Register a schema for MyClass (@DefaultSchema)"); }

Try / catch

try { parameterValues(...); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Could not determine the row function")) { /* prompt schema registration */ } throw e; }

Prevention

When it happens

Trigger: A constructor parameter is a POJO/complex type, the payload provides a Row for it, but the class was never registered with a schema (no @DefaultSchema annotation and no SchemaRegistry.register call).

Common situations: Custom PTransform constructor taking a user options/config class that lacks @DefaultSchema; class registered under a different ClassLoader in the expansion service; refactored class name no longer matching the registered schema.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

      List<Object> originalList = (List) valueFromRow;
      List<Object> decodedList = new ArrayList<>();
      for (Object obj : originalList) {
        if (genericType instanceof ParameterizedType) {
          Class<?> elementType =
              (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
          decodedList.add(getDecodedValueFromRow(elementType, obj, null));
        } else {
          throw new RuntimeException("Could not determine the generic type of the list");
        }
      }
      return decodedList;
    } else if (valueFromRow instanceof Row) {
      Row row = (Row) valueFromRow;
      SerializableFunction<Row, ?> fromRowFunc;
      try {
        fromRowFunc = SCHEMA_REGISTRY.getFromRowFunction(type);
      } catch (NoSuchSchemaException e) {
        throw new IllegalArgumentException(
            "Could not determine the row function for class " + type, e);
      }
      return fromRowFunc.apply(row);
    }
    throw new RuntimeException("Could not decode the value from Row " + valueFromRow);
  }

  @SuppressWarnings("argument")
  private Object[] getParameterValues(
      java.lang.reflect.Parameter[] parameters, Row constrtuctorRow, Type[] genericTypes) {
    ArrayList<Object> parameterValues = new ArrayList<>();
    for (int i = 0; i < parameters.length; ++i) {
      java.lang.reflect.Parameter parameter = parameters[i];
      Class<?> parameterClass = parameter.getType();
      Object parameterValue =
          getDecodedValueFromRow(parameterClass, constrtuctorRow.getValue(i), genericTypes[i]);
      parameterValues.add(parameterValue);
    }

View on GitHub (pinned to 12126d8942)