{"record":{"id":"012ab494a6c911b9","repo":"apache/beam","slug":"cannot-automatically-determine-a-field-type-from-a-row-class","errorCode":null,"errorMessage":"Cannot automatically determine a field type from a Row class as we cannot determine the schema. You should set a field type explicitly.","messagePattern":"Cannot automatically determine a field type from a Row class as we cannot determine the schema\\. You should set a field type explicitly\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/FieldTypeDescriptors.java","lineNumber":91,"sourceCode":"      case ROW:\n        return TypeDescriptors.rows();\n      default:\n        return PRIMITIVE_MAPPING.get(fieldType.getTypeName());\n    }\n  }\n\n  /** Get a {@link FieldType} from a {@link TypeDescriptor}. */\n  public static FieldType fieldTypeForJavaType(TypeDescriptor typeDescriptor) {\n    // TODO: Convert for registered logical types.\n    if (typeDescriptor.isArray()\n        || typeDescriptor.isSubtypeOf(TypeDescriptor.of(Collection.class))) {\n      return getArrayFieldType(typeDescriptor);\n    } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(Map.class))) {\n      return getMapFieldType(typeDescriptor);\n    } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(Iterable.class))) {\n      return getIterableFieldType(typeDescriptor);\n    } else if (typeDescriptor.isSubtypeOf(TypeDescriptor.of(Row.class))) {\n      throw new IllegalArgumentException(\n          \"Cannot automatically determine a field type from a Row class\"\n              + \" as we cannot determine the schema. You should set a field type explicitly.\");\n    } else {\n      TypeName typeName = PRIMITIVE_MAPPING.inverse().get(typeDescriptor);\n      if (typeName == null) {\n        throw new RuntimeException(\"Couldn't find field type for \" + typeDescriptor);\n      }\n      return FieldType.of(typeName);\n    }\n  }\n\n  private static FieldType getArrayFieldType(TypeDescriptor typeDescriptor) {\n    if (typeDescriptor.isArray()) {\n      if (typeDescriptor.getComponentType().getType().equals(byte.class)) {\n        return FieldType.BYTES;\n      } else {\n        return FieldType.array(fieldTypeForJavaType(typeDescriptor.getComponentType()));\n      }","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/FieldTypeDescriptors.java#L73-L109","documentation":"FieldTypeDescriptors.fieldTypeForJavaType infers a FieldType from a Java TypeDescriptor. Row (and Row subclasses) cannot be inferred because a Row class alone doesn't identify which schema it uses, so Beam explicitly rejects it with this IllegalArgumentException rather than guessing.","triggerScenarios":"Schema inference over a POJO/AutoValue class containing a property typed Row or a Row subtype, reached via getArrayFieldType/getIterableFieldType/getMapFieldType — e.g. List<Row> or a nested Row field — without an explicit FieldType.","commonSituations":"POJOs holding generic Row payloads; users migrating from TableRow/Row-based pipelines into typed schemas; container fields of Row without schema annotation.","solutions":["Replace the Row-typed field with a concrete schema-annotated class (POJO with @DefaultSchema or AutoValue).","Set the field type explicitly, e.g. FieldType.row(Schema) for the field via @SchemaField annotation or manual Schema building.","Use a TypeDescriptor-based supplier with a registered schema for the Row's logical type.","Catch this at schema-build time and provide FieldType.row(...) for the offending field."],"exampleFix":"// before\npublic Row getPayload() { ... }\n\n// after\n@SchemaField(fieldName = \"payload\", fieldType = \"ROW<...>\") // or concrete type\npublic PayloadRow getPayload() { ... } // PayloadRow annotated with @DefaultSchema","handlingStrategy":"validation","validationCode":"if (Row.class.isAssignableFrom(pojo.getClass())) throw new IllegalStateException(\"Row fields need explicit FieldType.row(schema)\");","typeGuard":"static <T> boolean hasRowFields(Class<T> c) {\n  return java.util.Arrays.stream(c.getDeclaredMethods())\n    .anyMatch(m -> m.getReturnType() == Row.class || Row.class.isAssignableFrom(m.getReturnType()));\n}","tryCatchPattern":"try { Schema.of(Pojo.class); }\ncatch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"from a Row class\")) {\n    throw new IllegalStateException(\"Provide explicit FieldType.row(...) or use a schema-annotated class\", e);\n  } throw e;\n}","preventionTips":["Avoid Row/TableRow fields in schema-inferred POJOs","Use concrete @DefaultSchema-annotated classes for nested rows","Build schemas manually when nesting generic rows"],"tags":["beam-schemas","row","type-inference"],"backgroundTag":"incompatible-source-type","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"}