{"record":{"id":"234b528481669787","repo":"apache/iceberg","slug":"unknown-type-for-int-field-type-name-integer-234b52","errorCode":null,"errorMessage":"Unknown type for int field. Type name: \" + integer.getClass().getName()","messagePattern":"Unknown type for int field\\. Type name: \" \\+ integer\\.getClass\\(\\)\\.getName\\(\\)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java","lineNumber":137,"sourceCode":"  public byte getByte(int ordinal) {\n    return (byte) (int) struct.get(ordinal, Integer.class);\n  }\n\n  @Override\n  public short getShort(int ordinal) {\n    return (short) (int) struct.get(ordinal, Integer.class);\n  }\n\n  @Override\n  public int getInt(int ordinal) {\n    Object integer = struct.get(ordinal, Object.class);\n\n    if (integer instanceof Integer) {\n      return (int) integer;\n    } else if (integer instanceof LocalDate) {\n      return (int) ((LocalDate) integer).toEpochDay();\n    } else {\n      throw new IllegalStateException(\n          \"Unknown type for int field. Type name: \" + integer.getClass().getName());\n    }\n  }\n\n  @Override\n  public long getLong(int ordinal) {\n    Object longVal = struct.get(ordinal, Object.class);\n\n    if (longVal instanceof Long) {\n      return (long) longVal;\n    } else if (longVal instanceof OffsetDateTime) {\n      return Duration.between(Instant.EPOCH, (OffsetDateTime) longVal).toNanos() / 1000;\n    } else if (longVal instanceof LocalDate) {\n      return ((LocalDate) longVal).toEpochDay();\n    } else {\n      throw new IllegalStateException(\n          \"Unknown type for long field. Type name: \" + longVal.getClass().getName());\n    }","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java#L119-L155","documentation":"StructInternalRow.getInt extracts a Spark INTEGER/DATE int value from the underlying Iceberg struct field. It accepts Integer or LocalDate; any other stored Java type means the runtime object's class doesn't match the expected column type, so it throws IllegalStateException with the actual class name.","triggerScenarios":"Reading a column whose Iceberg/Spark type mapping was wrong (e.g. the field actually holds Long, String, or BigDecimal) while Spark's expected schema declares an IntegerType/DateType at that ordinal — a struct-type/data mismatch between the provided schema and stored objects.","commonSituations":"Schema drift between table versions; supplying a wrong expected Spark schema in custom reads; custom Scan/GenericDataUtil conversions returning unexpected boxed types.","solutions":["Verify the expected Spark schema passed to the reader matches the actual Iceberg table schema for the int/date column","Check what class is printed in the message and fix the code that produces that type (e.g. wrap/convert Long to Integer, or use getLong for Long columns)","Update the Iceberg version if the underlying type-to-Java-class mapping changed for your type","Rebuild any cached table metadata after schema evolution"],"exampleFix":"// before\nrow.getInt(dateFieldOrdinal); // stored value is OffsetDateTime -> IllegalStateException\n// after\n// read the field with the accessor matching the actual stored type\nlong epochDay = row.getLong(ordinal); // or fix the producer to store LocalDate/Integer","handlingStrategy":"type-guard","validationCode":"Object v = struct.get(pos, javaClass);\nif (!(v instanceof Integer) && !(v instanceof LocalDate)) {\n  throw new IllegalStateException(\"expected Integer/LocalDate for int field, got \" + v.getClass());\n}","typeGuard":"boolean isIntBacked(Object v) { return v instanceof Integer || v instanceof LocalDate; }","tryCatchPattern":"try { int i = row.getInt(ordinal); } catch (IllegalStateException e) { /* inspect e.getMessage() class name and fix the producer schema */ }","preventionTips":["Keep the expected Spark schema identical to the Iceberg table schema","Run a one-time schema drift check between write and read paths","Use Iceberg's standard conversions rather than custom struct wrappers"],"tags":["spark","internalrow","type-mismatch","int"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}