{"record":{"id":"d7a5091e0a03825c","repo":"apache/beam","slug":"cannot-infer-schema-from-unparameterized-map","errorCode":null,"errorMessage":"Cannot infer schema from unparameterized map.","messagePattern":"Cannot infer schema from unparameterized map\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/StaticSchemaInference.java","lineNumber":181,"sourceCode":"      }\n    } else if (type.isSubtypeOf(TypeDescriptor.of(Map.class))) {\n      TypeDescriptor<Collection<?>> map = type.getSupertype(Map.class);\n      if (map.getType() instanceof ParameterizedType) {\n        ParameterizedType ptype = (ParameterizedType) map.getType();\n        java.lang.reflect.Type[] params = ptype.getActualTypeArguments();\n        checkArgument(params.length == 2);\n        FieldType keyType =\n            fieldFromType(\n                TypeDescriptor.of(params[0]), fieldValueTypeSupplier, alreadyVisitedSchemas);\n        FieldType valueType =\n            fieldFromType(\n                TypeDescriptor.of(params[1]), fieldValueTypeSupplier, alreadyVisitedSchemas);\n        checkArgument(\n            keyType.getTypeName().isPrimitiveType(),\n            \"Only primitive types can be map keys. type: \" + keyType.getTypeName());\n        return FieldType.map(keyType, valueType);\n      } else {\n        throw new RuntimeException(\"Cannot infer schema from unparameterized map.\");\n      }\n    } else if (type.isSubtypeOf(TypeDescriptor.of(CharSequence.class))) {\n      return FieldType.STRING;\n    } else if (type.isSubtypeOf(TypeDescriptor.of(ReadableInstant.class))) {\n      return FieldType.DATETIME;\n    } else if (type.getRawType().equals(LocalDate.class)) {\n      return FieldType.logicalType(SqlTypes.DATE);\n    } else if (type.getRawType().equals(LocalTime.class)) {\n      return FieldType.logicalType(SqlTypes.TIME);\n    } else if (type.getRawType().equals(LocalDateTime.class)) {\n      return FieldType.logicalType(SqlTypes.DATETIME);\n    } else if (type.getRawType().equals(java.time.Instant.class)) {\n      return FieldType.logicalType(new NanosInstant());\n    } else if (type.getRawType().equals(UUID.class)) {\n      return FieldType.logicalType(SqlTypes.UUID);\n    } else if (type.isSubtypeOf(TypeDescriptor.of(ByteBuffer.class))) {\n      return FieldType.BYTES;\n    } else if (type.isSubtypeOf(TypeDescriptor.of(Iterable.class))) {","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/StaticSchemaInference.java#L163-L199","documentation":"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.","triggerScenarios":"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.","commonSituations":"Legacy POJOs without generics, code refactored away from generic types, or reflection-supplied types that lose parameterization (e.g. raw types from Object fields).","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)."],"exampleFix":"// before\nprivate Map data; // raw map\n// after\nprivate Map<String, Integer> data;","handlingStrategy":"type-guard","validationCode":"for (java.lang.reflect.Field f : pojoClass.getDeclaredFields()) {\n  if (Map.class.isAssignableFrom(f.getType())\n      && f.getGenericType() instanceof Class) {\n    throw new IllegalArgumentException(\"Raw Map field: \" + f.getName());\n  }\n}","typeGuard":"boolean hasParameterizedMap(java.lang.reflect.Field f) {\n  return f.getGenericType() instanceof java.lang.reflect.ParameterizedType\n      && Map.class.isAssignableFrom(f.getType());\n}","tryCatchPattern":"try {\n  Schema s = Schema.of(pojoClass);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"unparameterized map\")) {\n    throw new IllegalStateException(\"Parameterize Map fields, e.g. Map<String, Integer>\", e);\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["java","schema","generics","map"],"backgroundTag":"missing-required-argument","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"}