{"record":{"id":"f3066a257d9bebf8","repo":"apache/iceberg","slug":"unknown-type-for-long-field-type-name-longval-f3066a","errorCode":null,"errorMessage":"Unknown type for long field. Type name: + longVal.getClass().getName()","messagePattern":"Unknown type for long field\\. Type name: \\+ longVal\\.getClass\\(\\)\\.getName\\(\\)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java","lineNumber":151,"sourceCode":"      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    }\n  }\n\n  @Override\n  public float getFloat(int ordinal) {\n    return struct.get(ordinal, Float.class);\n  }\n\n  @Override\n  public double getDouble(int ordinal) {\n    return struct.get(ordinal, Double.class);\n  }\n\n  @Override\n  public Decimal getDecimal(int ordinal, int precision, int scale) {\n    return isNullAt(ordinal) ? null : getDecimalInternal(ordinal);\n  }","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/StructInternalRow.java#L133-L169","documentation":"StructInternalRow.getLong converts the stored field value to a Spark long, accepting Long, OffsetDateTime (Timestamptz), LocalDateTime-backed values, or LocalDate (Date). Any other stored type triggers an IllegalStateException naming the actual class.","triggerScenarios":"Calling getLong(ordinal) when the struct field holds an unexpected object type, e.g. an Integer stored for a Long column, or a type drifted from the declared Iceberg schema.","commonSituations":"Schema evolution/type promotion (int -> long) where old data or views still supply Integer; timestamp representation mismatches between table spec versions; custom readers storing unexpected Java classes.","solutions":["Read the field with getInt when the stored value is an Integer, or convert the stored type to Long before reading","Align the Iceberg schema with the physical data and rewrite metadata/data if types drifted","Verify which Java representation the column actually stores (Long, OffsetDateTime, LocalDate) and use the matching getter"],"exampleFix":"// before\nlong v = structRow.getLong(ordinal); // stored Integer\n// after\nObject val = ((StructLike) structRow.getStruct(ordinal, null)).get(ordinal, null);\nlong v = val instanceof Integer ? (Integer) val : structRow.getLong(ordinal);","handlingStrategy":"type-guard","validationCode":"Object v = structLike.get(ordinal, null);\nif (!(v instanceof Long || v instanceof OffsetDateTime || v instanceof LocalDateTime || v instanceof LocalDate)) {\n  throw new IllegalArgumentException(\"Field \" + ordinal + \" is not long-compatible: \" + v.getClass());\n}","typeGuard":"boolean isLongField(Object v) {\n  return v instanceof Long || v instanceof java.time.OffsetDateTime || v instanceof java.time.LocalDateTime || v instanceof java.time.LocalDate;\n}","tryCatchPattern":"try {\n  return row.getLong(ordinal);\n} catch (IllegalStateException e) {\n  // handle Integer-stored values via getInt or explicit conversion\n}","preventionTips":["After int->long type promotion, rewrite or refresh data so stored representations match","Use getLong only for Timestamp/Timestamptz/Long fields","Verify the Iceberg timestamp representation (OffsetDateTime vs micros long) before reading"],"tags":["type-mismatch","spark","internal-row","long"],"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"}