apache/beam · error · RuntimeException
Cannot infer schema from unparameterized map.
Error message
Cannot infer schema from unparameterized map.
What it means
When fieldFromType infers a schema field from a java.util.Map-typed field, it needs the map's type parameters to build FieldType.map(keyType, valueType). If the Map type is raw (no generic parameters), the key/value types cannot be inferred and this RuntimeException is thrown.
Solutions
- Parameterize the map field with concrete generic types, e.g. Map<String, Integer>.
- If generics cannot be added, supply the schema explicitly (Schema.builder().addMapField(...)) instead of inferring.
- Note keys must also be primitive schema types; parameterize with a primitive key type like String.
- Ensure the TypeDescriptor passed to inference retains type parameters (avoid raw Class-based descriptors).
Example fix
// before private Map data; // raw map // after private Map<String, Integer> data;
Defensive patterns
Strategy: type-guard
Validate before calling
for (java.lang.reflect.Field f : pojoClass.getDeclaredFields()) {
if (Map.class.isAssignableFrom(f.getType())
&& f.getGenericType() instanceof Class) {
throw new IllegalArgumentException("Raw Map field: " + f.getName());
}
} Type guard
boolean hasParameterizedMap(java.lang.reflect.Field f) {
return f.getGenericType() instanceof java.lang.reflect.ParameterizedType
&& Map.class.isAssignableFrom(f.getType());
} Try / catch
try {
Schema s = Schema.of(pojoClass);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("unparameterized map")) {
throw new IllegalStateException("Parameterize Map fields, e.g. Map<String, Integer>", e);
}
throw e;
} Prevention
- Always declare generic type parameters on Map fields
- Lint for raw types in schema POJOs
- Avoid Object/raw-Class-based descriptors when calling inference APIs
When it happens
Trigger: Schema inference on a POJO field declared as a raw Map (e.g. `private Map data;` instead of `Map<String, Integer>`), passed via fieldFromType from fieldType/keyType/valueType.
Common situations: Legacy POJOs without generics, code refactored away from generic types, or reflection-supplied types that lose parameterization (e.g. raw types from Object fields).
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Cannot infer schema from unparameterized collection.
- is not nullable in Map field
- Arrow schema conversion does not support Beam type
- Cannot call getFromRowFunction when there is no schema
- Cannot call getSchema when there is no schema
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d7a5091e0a03825c.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/StaticSchemaInference.java:181
}
} else if (type.isSubtypeOf(TypeDescriptor.of(Map.class))) {
TypeDescriptor<Collection<?>> map = type.getSupertype(Map.class);
if (map.getType() instanceof ParameterizedType) {
ParameterizedType ptype = (ParameterizedType) map.getType();
java.lang.reflect.Type[] params = ptype.getActualTypeArguments();
checkArgument(params.length == 2);
FieldType keyType =
fieldFromType(
TypeDescriptor.of(params[0]), fieldValueTypeSupplier, alreadyVisitedSchemas);
FieldType valueType =
fieldFromType(
TypeDescriptor.of(params[1]), fieldValueTypeSupplier, alreadyVisitedSchemas);
checkArgument(
keyType.getTypeName().isPrimitiveType(),
"Only primitive types can be map keys. type: " + keyType.getTypeName());
return FieldType.map(keyType, valueType);
} else {
throw new RuntimeException("Cannot infer schema from unparameterized map.");
}
} else if (type.isSubtypeOf(TypeDescriptor.of(CharSequence.class))) {
return FieldType.STRING;
} else if (type.isSubtypeOf(TypeDescriptor.of(ReadableInstant.class))) {
return FieldType.DATETIME;
} else if (type.getRawType().equals(LocalDate.class)) {
return FieldType.logicalType(SqlTypes.DATE);
} else if (type.getRawType().equals(LocalTime.class)) {
return FieldType.logicalType(SqlTypes.TIME);
} else if (type.getRawType().equals(LocalDateTime.class)) {
return FieldType.logicalType(SqlTypes.DATETIME);
} else if (type.getRawType().equals(java.time.Instant.class)) {
return FieldType.logicalType(new NanosInstant());
} else if (type.getRawType().equals(UUID.class)) {
return FieldType.logicalType(SqlTypes.UUID);
} else if (type.isSubtypeOf(TypeDescriptor.of(ByteBuffer.class))) {
return FieldType.BYTES;
} else if (type.isSubtypeOf(TypeDescriptor.of(Iterable.class))) {View on GitHub (pinned to 12126d8942)