apache/beam · error · java.lang.RuntimeException
Could not determine a valid schema for parameter class
Error message
Could not determine a valid schema for parameter class
What it means
The service asked the SchemaRegistry for a schema of a parameter class and either got a schema with zero fields (which cannot be mapped from the payload row) or had to wrap NoSuchSchemaException. A usable, non-empty schema is required to map payload rows onto the parameter type.
Solutions
- Annotate the parameter class with @DefaultSchema(JavaFieldSchema.class) (or implement a SchemaProvider) and register it so SchemaRegistry can produce a non-empty schema.
- Ensure the class has at least one schema-able field; empty classes cannot be mapped from payload rows.
- Recompile so schema coders/field metadata are embedded, and redeploy the expansion service with the updated classes.
- Use a supported parameter type (POJO, AVRO record, Row) instead of unstructured types.
Example fix
// before
class Config { }
// after
@DefaultSchema(JavaFieldSchema.class)
class Config { public final String name; public Config(String name){this.name=name;} } Defensive patterns
Strategy: validation
Validate before calling
try {
Schema s = SchemaRegistry.getDefault().getSchema(Config.class);
if (s == null || s.getFieldCount() == 0) throw new IllegalStateException("Config has no usable schema; add @DefaultSchema and fields");
} catch (NoSuchSchemaException e) { throw new IllegalStateException("Register a schema for Config", e); } Try / catch
try {
return getTransform(payload);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Could not determine a valid schema")) {
throw new InvalidExpansionRequest("Parameter type lacks a registered non-empty schema", e);
}
throw e;
} Prevention
- Annotate every parameter POJO with @DefaultSchema(JavaFieldSchema.class) or an AVRO/POJO provider.
- Never use field-less classes as builder parameters for expansion.
- Register custom SchemaProviders before serving expansion requests.
- Verify schema resolution in unit tests via SchemaRegistry.getSchema().
When it happens
Trigger: Resolving a parameter type whose class has no registered schema, or whose schema registers zero fields (e.g. an empty @DefaultSchema class), during getParameterSchema used by arrayFieldSchema/schema paths.
Common situations: Parameter POJO missing @DefaultSchema annotation and schema provider; Java class compiled without schema field registration; using types like Object or maps not supported by the schema registry.
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
- Cannot find Spanner table.
- Cannot merge schemas with different numbers of fields…
- Cannot merge two types: +fieldType1.getTypeName()+ and…
- Config schema provided with the expansion request
- Converting to Beam schema type is not supported
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/827a4ea9a7ef6100.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java:260
private static boolean isPrimitiveOrWrapperOrString(java.lang.Class<?> type) {
return ClassUtils.isPrimitiveOrWrapper(type) || type == String.class;
}
private Schema getParameterSchema(Class<?> parameterClass) {
Schema parameterSchema;
try {
parameterSchema = SCHEMA_REGISTRY.getSchema(parameterClass);
} catch (NoSuchSchemaException e) {
SCHEMA_REGISTRY.registerSchemaProvider(parameterClass, new JavaFieldSchema());
try {
parameterSchema = SCHEMA_REGISTRY.getSchema(parameterClass);
} catch (NoSuchSchemaException e1) {
throw new RuntimeException(e1);
}
if (parameterSchema != null && parameterSchema.getFieldCount() == 0) {
throw new RuntimeException(
"Could not determine a valid schema for parameter class " + parameterClass);
}
}
return parameterSchema;
}
private boolean parametersCompatible(
java.lang.reflect.Parameter[] methodParameters, Row constructorRow) {
Schema constructorSchema = constructorRow.getSchema();
if (methodParameters.length != constructorSchema.getFieldCount()) {
return false;
}
for (int i = 0; i < methodParameters.length; i++) {
java.lang.reflect.Parameter parameterFromReflection = methodParameters[i];
Field parameterFromPayload = constructorSchema.getField(i);
String paramNameFromReflection = parameterFromReflection.getName();
View on GitHub (pinned to 12126d8942)