{"record":{"id":"32ae20261849e0a6","repo":"apache/iceberg","slug":"cannot-determine-comparator-for-type-type","errorCode":null,"errorMessage":"Cannot determine comparator for type: + type","messagePattern":"Cannot determine comparator for type: \\+ type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/types/Comparators.java","lineNumber":77,"sourceCode":"    return new ListComparator<>(list);\n  }\n\n  public static <K, V> Comparator<Map<K, V>> forType(Types.MapType mapType) {\n    return new MapComparator<>(mapType);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> Comparator<T> forType(Type.PrimitiveType type) {\n    Comparator<?> cmp = COMPARATORS.get(type);\n    if (cmp != null) {\n      return (Comparator<T>) cmp;\n    } else if (type instanceof Types.FixedType) {\n      return (Comparator<T>) Comparators.unsignedBytes();\n    } else if (type instanceof Types.DecimalType) {\n      return (Comparator<T>) Comparator.naturalOrder();\n    }\n\n    throw new UnsupportedOperationException(\"Cannot determine comparator for type: \" + type);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private static <T> Comparator<T> internal(Type type) {\n    if (type.isPrimitiveType()) {\n      return forType(type.asPrimitiveType());\n    } else if (type.isStructType()) {\n      return (Comparator<T>) forType(type.asStructType());\n    } else if (type.isListType()) {\n      return (Comparator<T>) forType(type.asListType());\n    } else if (type.isMapType()) {\n      return (Comparator<T>) forType(type.asMapType());\n    }\n\n    throw new UnsupportedOperationException(\"Cannot determine comparator for type: \" + type);\n  }\n\n  private static class StructLikeComparator implements Comparator<StructLike> {","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/types/Comparators.java#L59-L95","documentation":"Comparators.forType() builds a java.util.Comparator for a given Iceberg primitive type. Types not covered by its if/else chain (e.g. non-primitive/nested types passed directly) have no comparator defined, so the library throws UnsupportedOperationException. Comparators are only defined for primitive types; nested types must go through the comparator builder.","triggerScenarios":"Calling Comparators.forType(Types.NestedField.type()) or forType with a StructType/ListType/MapType instead of a primitive type; passing an unknown or UNKNOWN type.","commonSituations":"Passing the whole field type instead of field.type().typeId()'s primitive; sorting/merging code hitting a newly added spec type (e.g. geometry/geography) on an older client version.","solutions":["Pass a primitive type (use field.type().asPrimitiveType()) to forType","Use Comparators.comparator(schema) builder for nested struct/list/map types instead of forType","Upgrade Iceberg if the type is a newer spec type supported by a newer version"],"exampleFix":"// before\nComparator<T> c = Comparators.forType(structType);\n// after\nComparator<T> c = Comparators.forType(field.type().asPrimitiveType());","handlingStrategy":"type-guard","validationCode":"if (!type.isPrimitiveType()) throw new IllegalArgumentException(\"forType requires a primitive type: \" + type);","typeGuard":"boolean hasComparator(Type t) { return t.isPrimitiveType(); }","tryCatchPattern":"try { cmp = Comparators.forType(type); } catch (UnsupportedOperationException e) { cmp = null; /* handle non-comparable type */ }","preventionTips":["Use the Comparators.comparator(schema) builder for nested types","Pass asPrimitiveType() rather than raw field types","Check for newer spec types before comparing"],"tags":["java","comparator","types","unsupported-operation"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}