{"record":{"id":"5a14c6f361c2a7d8","repo":"apache/beam","slug":"expected-a-schema-with-a-single-array-field-but-received","errorCode":null,"errorMessage":"Expected a schema with a single array field but received ","messagePattern":"Expected a schema with a single array field but received ","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java","lineNumber":298,"sourceCode":"      boolean ignoreFieldName =\n          FIELD_NAME_IGNORE_PATTERN.matcher(parameterFromPayload.getName()).matches();\n\n      if (!ignoreFieldName && !paramNameFromReflection.equals(parameterFromPayload.getName())) {\n        // Parameter name through reflection is from the class file (not through synthesizing,\n        // hence we can validate names)\n        return false;\n      }\n\n      Class<?> parameterClass = parameterFromReflection.getType();\n      if (isPrimitiveOrWrapperOrString(parameterClass)) {\n        continue;\n      }\n\n      // We perform additional validation for arrays and non-primitive types.\n      if (parameterClass.isArray()) {\n        Class<?> arrayFieldClass = parameterClass.getComponentType();\n        if (parameterFromPayload.getType().getTypeName() != TypeName.ARRAY) {\n          throw new RuntimeException(\n              \"Expected a schema with a single array field but received \"\n                  + parameterFromPayload.getType().getTypeName());\n        }\n\n        // Following is a best-effort validation that may not cover all cases. Idea is to resolve\n        // ambiguities as much as possible to determine an exact match for the given set of\n        // parameters. If there are ambiguities, the expansion will fail.\n        if (!isPrimitiveOrWrapperOrString(arrayFieldClass)) {\n          @Nullable Collection<Row> values = constructorRow.getArray(i);\n          Schema arrayFieldSchema = getParameterSchema(arrayFieldClass);\n          if (arrayFieldSchema == null) {\n            throw new RuntimeException(\"Could not determine a schema for type \" + arrayFieldClass);\n          }\n          if (values != null) {\n            @Nullable Row firstItem = values.iterator().next();\n            if (firstItem != null && !firstItem.getSchema().assignableTo(arrayFieldSchema)) {\n              return false;\n            }","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java#L280-L316","documentation":"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.","triggerScenarios":"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[]).","commonSituations":"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).","solutions":["Change the transform's builder method signature to use List<T> instead of T[] (or vice versa) to match the payload type.","Fix the payload schema so the field's TypeName is ARRAY for that parameter.","Regenerate the expansion payload with a matching SDK version so type mappings agree."],"exampleFix":"// before\npublic MyTransform withNames(String[] names) {...}\n// after\npublic MyTransform withNames(List<String> names) {...}  // matches ARRAY-typed payload field","handlingStrategy":"type-guard","validationCode":"for (Parameter p : method.getParameters()) {\n  if (p.getType().isArray()) {\n    String t = payloadSchema.getField(p.getName()).getType().getTypeName();\n    if (t != \"ARRAY\") throw new IllegalStateException(p.getName() + \" must be ARRAY in payload schema\");\n  }\n}","typeGuard":"function isArrayTyped(field) { return field.getType().getTypeName() === 'ARRAY'; }","tryCatchPattern":"try {\n  return getTransform(payload);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"single array field\")) {\n    throw new InvalidExpansionRequest(\"Payload field type does not match array parameter; use List<T> or ARRAY payload\", e);\n  }\n  throw e;\n}","preventionTips":["Prefer List<T> over raw arrays T[] in cross-language-exposed builder methods.","Validate payload schema type names against method signatures before submitting expansion.","Regenerate payloads whenever the transform signature changes.","Test parameter compatibility locally with Schema+Row round-trips."],"tags":["java","schema","type-mismatch","beam-expansion-service"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}