{"record":{"id":"93445c793d0795e6","repo":"apache/beam","slug":"unsupported-row-type-valueclass","errorCode":null,"errorMessage":"Unsupported row type: {valueClass}","messagePattern":"Unsupported row type: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/IcebergUtils.java","lineNumber":644,"sourceCode":"        break;\n      case BYTES:\n        // Beam uses byte[]. Iceberg represents `binary` as a ByteBuffer but `fixed` as a byte[].\n        rowBuilder.addValue(\n            icebergValue instanceof byte[]\n                ? (byte[]) icebergValue\n                : ((ByteBuffer) icebergValue).array());\n        break;\n      case ROW:\n        Schema nestedSchema =\n            checkArgumentNotNull(\n                field.getType().getRowSchema(),\n                \"Corrupted schema: Row type did not have associated nested schema.\");\n        if (icebergValue instanceof Record) {\n          rowBuilder.addValue(icebergRecordToBeamRow(nestedSchema, (Record) icebergValue));\n        } else if (icebergValue instanceof StructLike) {\n          rowBuilder.addValue(structToRow(nestedSchema, (StructLike) icebergValue));\n        } else {\n          throw new UnsupportedOperationException(\n              \"Unsupported row type: \" + icebergValue.getClass());\n        }\n        break;\n      case LOGICAL_TYPE:\n        rowBuilder.addValue(getLogicalTypeValue(icebergValue, field.getType()));\n        break;\n      default:\n        throw new UnsupportedOperationException(\n            \"Unsupported Beam type: \" + field.getType().getTypeName());\n    }\n  }\n\n  private static DateTime getBeamDateTimeValue(Object icebergValue) {\n    long micros;\n    if (icebergValue instanceof OffsetDateTime) {\n      micros = DateTimeUtil.microsFromTimestamptz((OffsetDateTime) icebergValue);\n    } else if (icebergValue instanceof LocalDateTime) {\n      micros = DateTimeUtil.microsFromTimestamp((LocalDateTime) icebergValue);","sourceCodeStart":626,"sourceCodeEnd":662,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/IcebergUtils.java#L626-L662","documentation":"In addIcebergValue, Beam Row-typed fields must hold either an org.apache.hadoop.hive.ql.exec.Record-style org.apache.avro.generic.Record-like Record or a StructLike; any other object in a Row-type field is rejected with UnsupportedOperationException, since the nested Beam Row cannot be constructed from it.","triggerScenarios":"A nested Iceberg struct field's value is neither a Record nor a StructLike — e.g. the value is a java.util.Map, a List, a generic Object produced by a custom deserializer, or the Iceberg record implementation returns raw containers for struct columns.","commonSituations":"Custom record readers/writers populating struct fields with Maps instead of Iceberg Record/StructLike; third-party libraries returning wrapped values; mixing Iceberg runtime versions where the record implementation changed class.","solutions":["Ensure nested struct values implement org.apache.iceberg.types.Types.StructType-compatible StructLike (use iceberg's GenericData.Record or copy via the table's struct projection)","Convert Maps manually: build a Record from the map keys following the nested schema before adding it to the row","Check for version mismatches between the Iceberg runtime used to write and read records","If you control the source, wrap the value: GenericData.Record rec = new GenericData.Record(nestedSchema.asStruct()); copy fields; then convert"],"exampleFix":"// before\nrowBuilder.addValue(someJavaMapForStructField);\n// after\nRecord rec = GenericRecordUtil.recordFromMap(nestedSchema.asStruct(), someJavaMapForStructField);\nrowBuilder.addValue(icebergRecordToBeamRow(nestedSchema, rec));","handlingStrategy":"type-guard","validationCode":"Object nested = record.getField(i);\nif (!(nested instanceof org.apache.iceberg.data.Record) && !(nested instanceof StructLike)) {\n  throw new IllegalArgumentException(\"Nested struct field must be Record/StructLike, got \" + nested.getClass());\n}","typeGuard":"boolean isStructLike(Object v) {\n  return v instanceof org.apache.iceberg.data.Record || v instanceof StructLike;\n}","tryCatchPattern":"try {\n  row = structToRow(schema, struct);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().startsWith(\"Unsupported row type\")) {\n    // wrap value into a Record before retrying\n  } else { throw e; }\n}","preventionTips":["Use iceberg's GenericData.Record for nested structs","Avoid Maps for struct columns in custom deserializers","Pin one Iceberg runtime version across the pipeline"],"tags":["java","iceberg","beam","nested-struct","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}