apache/iceberg · error · UnsupportedOperationException
Expected value to be timestamp: ${valueType.catalogString()}
Error message
Expected value to be timestamp: ${valueType.catalogString()} What it means
The hours() SQL catalog function accepts only timestamp (or timestamp_ntz) values since hour extraction is defined on instants. Any other type, including DATE, fails bind with UnsupportedOperationException naming the actual type.
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/functions/HoursFunction.java:43
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.TimestampNTZType;
import org.apache.spark.sql.types.TimestampType;
/**
* A Spark function implementation for the Iceberg hour transform.
*
* <p>Example usage: {@code SELECT system.hours('source_col')}.
*/
public class HoursFunction extends UnaryUnboundFunction {
@Override
protected BoundFunction doBind(DataType valueType) {
if (valueType instanceof TimestampType) {
return new TimestampToHoursFunction();
} else if (valueType instanceof TimestampNTZType) {
return new TimestampNtzToHoursFunction();
} else {
throw new UnsupportedOperationException(
"Expected value to be timestamp: " + valueType.catalogString());
}
}
@Override
public String description() {
return name()
+ "(col) - Call Iceberg's hour transform\n"
+ " col :: source column (must be timestamp)";
}
@Override
public String name() {
return "hours";
}
public static class TimestampToHoursFunction extends BaseScalarFunction<Integer> {
// magic method used in codegenView on GitHub (pinned to 86d9c8fc54)
Solutions
- Cast date to timestamp if an implicit midnight hour is intended: system.hours(CAST(d AS TIMESTAMP))
- Use system.days() for DATE columns instead
- Cast string values to TIMESTAMP before calling hours()
Example fix
// before
spark.sql("SELECT system.hours(event_date) FROM tbl") -- event_date is DATE
// after
spark.sql("SELECT system.days(event_date) FROM tbl") Defensive patterns
Strategy: type-guard
Validate before calling
// hours() requires timestamp-like types
boolean hoursOk(DataType t) { return t instanceof TimestampType || t instanceof TimestampNTZType; } Type guard
boolean hoursOk(DataType t) { return t instanceof TimestampType || t instanceof TimestampNTZType; } Prevention
- Use days()/months()/years() for DATE columns, hours() only for timestamps
- Cast DATE to TIMESTAMP only when an hour component is meaningful
- Validate input column types in generated SQL pipelines
When it happens
Trigger: Calling system.hours(col) where col is DATE, string, or another non-timestamp type.
Common situations: Passing a date column to hours() (a date has no hour component); passing string timestamps without casting; mixing up days()/hours() functions.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Expected value to be date or timestamp: ${valueType.catalogS
- Expected value to be date or timestamp: ${valueType.catalogS
- Expected number of buckets to be tinyint, shortint or int
- Expected value to be date or timestamp: ${valueType.catalogS
- Expected value to be date or timestamp: ${valueType.catalogS
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/2ba2502b8330dbf2.
Report an issue: GitHub.