apache/beam · error · java.lang.RuntimeException

Expected a schema with a single array field but received

Error message

Expected a schema with a single array field but received 

What it means

During parameter compatibility checking, the Java parameter is an array type but the corresponding field in the payload schema row is not an ARRAY type. The service expects an array-typed payload field for every array parameter.

Solutions

  1. Change the transform's builder method signature to use List<T> instead of T[] (or vice versa) to match the payload type.
  2. Fix the payload schema so the field's TypeName is ARRAY for that parameter.
  3. Regenerate the expansion payload with a matching SDK version so type mappings agree.

Example fix

// before
public MyTransform withNames(String[] names) {...}
// after
public MyTransform withNames(List<String> names) {...}  // matches ARRAY-typed payload field
Defensive patterns

Strategy: type-guard

Validate before calling

for (Parameter p : method.getParameters()) {
  if (p.getType().isArray()) {
    String t = payloadSchema.getField(p.getName()).getType().getTypeName();
    if (t != "ARRAY") throw new IllegalStateException(p.getName() + " must be ARRAY in payload schema");
  }
}

Type guard

function isArrayTyped(field) { return field.getType().getTypeName() === 'ARRAY'; }

Try / catch

try {
  return getTransform(payload);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().contains("single array field")) {
    throw new InvalidExpansionRequest("Payload field type does not match array parameter; use List<T> or ARRAY payload", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Expansion payload's schema declares a scalar/repeated type other than ARRAY for a builder-method parameter whose Java type is an array (e.g. int[]).

Common situations: Hand-written or generated payload using a list type where the transform signature uses a raw array (String[]), or vice versa; language mapping differences (Python list -> Java List, not Java array).

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/5a14c6f361c2a7d8. Report an issue: GitHub.

Appendix: source

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

      boolean ignoreFieldName =
          FIELD_NAME_IGNORE_PATTERN.matcher(parameterFromPayload.getName()).matches();

      if (!ignoreFieldName && !paramNameFromReflection.equals(parameterFromPayload.getName())) {
        // Parameter name through reflection is from the class file (not through synthesizing,
        // hence we can validate names)
        return false;
      }

      Class<?> parameterClass = parameterFromReflection.getType();
      if (isPrimitiveOrWrapperOrString(parameterClass)) {
        continue;
      }

      // We perform additional validation for arrays and non-primitive types.
      if (parameterClass.isArray()) {
        Class<?> arrayFieldClass = parameterClass.getComponentType();
        if (parameterFromPayload.getType().getTypeName() != TypeName.ARRAY) {
          throw new RuntimeException(
              "Expected a schema with a single array field but received "
                  + parameterFromPayload.getType().getTypeName());
        }

        // Following is a best-effort validation that may not cover all cases. Idea is to resolve
        // ambiguities as much as possible to determine an exact match for the given set of
        // parameters. If there are ambiguities, the expansion will fail.
        if (!isPrimitiveOrWrapperOrString(arrayFieldClass)) {
          @Nullable Collection<Row> values = constructorRow.getArray(i);
          Schema arrayFieldSchema = getParameterSchema(arrayFieldClass);
          if (arrayFieldSchema == null) {
            throw new RuntimeException("Could not determine a schema for type " + arrayFieldClass);
          }
          if (values != null) {
            @Nullable Row firstItem = values.iterator().next();
            if (firstItem != null && !firstItem.getSchema().assignableTo(arrayFieldSchema)) {
              return false;
            }

View on GitHub (pinned to 12126d8942)