{"record":{"id":"b5583acbb59e695b","repo":"apache/iceberg","slug":"wrong-class-expected-s-but-was-s-for-object","errorCode":null,"errorMessage":"Wrong class, expected %s, but was %s, for object: %s","messagePattern":"Wrong class, expected (.+?), but was (.+?), for object: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/PartitionData.java","lineNumber":129,"sourceCode":"  }\n\n  public void clear() {\n    Arrays.fill(data, null);\n  }\n\n  @Override\n  public int size() {\n    return size;\n  }\n\n  @Override\n  public <T> T get(int pos, Class<T> javaClass) {\n    Object value = get(pos);\n    if (value == null || javaClass.isInstance(value)) {\n      return javaClass.cast(value);\n    }\n\n    throw new IllegalArgumentException(\n        String.format(\n            \"Wrong class, expected %s, but was %s, for object: %s\",\n            javaClass.getName(), value.getClass().getName(), value));\n  }\n\n  @Override\n  public Object get(int pos) {\n    if (pos >= data.length) {\n      return null;\n    }\n\n    if (data[pos] instanceof byte[]) {\n      byte[] copied = Arrays.copyOf((byte[]) data[pos], ((byte[]) data[pos]).length);\n      return ByteBuffer.wrap(copied);\n    }\n\n    return data[pos];\n  }","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/PartitionData.java#L111-L147","documentation":"PartitionData.get(pos) reads the value at a partition-struct position and casts it to the expected Java class. If the value is null it returns null; if the stored value's class is not an instance of javaClass (e.g. internal schema/field-type mismatch between expected partition type and actual data), it throws IllegalArgumentException. This signals an internal invariant violation: the partition field's type and the stored object disagree.","triggerScenarios":"Calling PartitionData.get(pos, Class) with a class that does not match the field's declared type at that position — e.g. get(0, Long.class) when the partition field is an int, or reading a PartitionData produced with a different PartitionSpec/schema than the one expected (spec evolution mismatch).","commonSituations":"Custom readers/writers or Spark/Flink projections assuming the wrong partition field type; partition spec evolution where cached partition type no longer matches stored data; test code constructing PartitionData with values of the wrong Java type (e.g. Integer vs Long).","solutions":["Match the requested class to the partition field's Iceberg type: Integer for int/date, Long for long/timestamp, String, ByteBuffer for binary, etc.","Use the correct PartitionSpec/schema when constructing or reading PartitionData — stale cached types cause mismatched positions.","Wrap access with a check: Object v = partitionData.get(pos); assert javaClass.isInstance(v) before casting, to produce a clearer failure.","For conversions, read as Object and convert explicitly (e.g. ((Number) v).longValue()) instead of assuming the class."],"exampleFix":"// before\nLong value = partitionData.get(0, Long.class); // field is actually int\n// after\nInteger value = partitionData.get(0, Integer.class);","handlingStrategy":"type-guard","validationCode":"Types.NestedField field = spec.partitionType().fields().get(pos);\nClass<?> expected = expectedJavaClass(field.type()); // map Iceberg type to Java class before calling get()","typeGuard":"Object raw = partitionData.get(pos);\nT value = javaClass.isInstance(raw) ? javaClass.cast(raw) : null;","tryCatchPattern":"try {\n  Long v = partitionData.get(pos, Long.class);\n} catch (IllegalArgumentException e) {\n  if (!e.getMessage().startsWith(\"Wrong class\")) throw e;\n  // re-read with correct type from spec.partitionType()\n}","preventionTips":["Derive the expected Java class from spec.partitionType().fields().get(pos).type(), never hardcode it.","Refresh cached PartitionSpec/schema after spec evolution.","In tests, build PartitionData values with the exact Java types Iceberg maps (int->Integer, long->Long, etc.)."],"tags":["type-mismatch","partition-data","class-cast","java"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}