apache/iceberg · error · java.lang.UnsupportedOperationException
Expected value to be date or timestamp: ${valueType.catalogS
Error message
Expected value to be date or timestamp: ${valueType.catalogString()} What it means
Iceberg's days(x) Spark transform function only accepts date, timestamp, or timestamp_ntz inputs. Binding any other value type (numeric, string, etc.) fails with this UnsupportedOperationException, appending the offending type's catalogString to the message. Thrown during query analysis via doBind.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/functions/DaysFunction.java:48
import org.apache.spark.sql.types.TimestampType;
/**
* A Spark function implementation for the Iceberg day transform.
*
* <p>Example usage: {@code SELECT system.days('source_col')}.
*/
public class DaysFunction extends UnaryUnboundFunction {
@Override
protected BoundFunction doBind(DataType valueType) {
if (valueType instanceof DateType) {
return new DateToDaysFunction();
} else if (valueType instanceof TimestampType) {
return new TimestampToDaysFunction();
} else if (valueType instanceof TimestampNTZType) {
return new TimestampNtzToDaysFunction();
} else {
throw new UnsupportedOperationException(
"Expected value to be date or timestamp: " + valueType.catalogString());
}
}
@Override
public String description() {
return name()
+ "(col) - Call Iceberg's day transform\n"
+ " col :: source column (must be date or timestamp)";
}
@Override
public String name() {
return "days";
}
protected abstract static class BaseToDaysFunction extends BaseScalarFunction<Integer>
implements ReducibleFunction<Integer, Integer> {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Cast the column first: days(CAST(ts_str AS TIMESTAMP)).
- Use to_date/to_timestamp to convert string dates before applying days().
- If the value is an epoch number, convert to timestamp, e.g. days(timestamp_millis(epoch_col)).
- Fix the table schema/column type if the partition spec was intended for a temporal column.
Example fix
// before SELECT days(ts_str) FROM t -- ts_str is STRING // after SELECT days(CAST(ts_str AS TIMESTAMP)) FROM t
Defensive patterns
Strategy: validation
Validate before calling
// Spark Scala
val dt = df.schema("value_col").dataType
require(dt == org.apache.spark.sql.types.DateType || dt.typeName.startsWith("timestamp"),
s"days() requires DATE or TIMESTAMP, got: ${dt.catalogString}") Type guard
def isTemporalType(dt: org.apache.spark.sql.types.DataType): Boolean = dt == org.apache.spark.sql.types.DateType || dt.isInstanceOf[org.apache.spark.sql.types.TimestampType] || dt.typeName == "timestamp_ntz"
Try / catch
try {
df.select(expr("days(ts_col)"))
} catch {
case e: UnsupportedOperationException if e.getMessage.startsWith("Expected value to be date or timestamp") =>
throw new IllegalArgumentException("days() needs a DATE/TIMESTAMP column; cast or use to_date/to_timestamp", e)
} Prevention
- Check the column type with printSchema/DESCRIBE TABLE before temporal transforms
- Parse string dates with to_date/to_timestamp before days()
- Never pass epoch numeric columns directly — convert with timestamp_millis()
- In partition specs, ensure the partitioned column is DATE or TIMESTAMP
When it happens
Trigger: Calling days(value) where value is a StringType (e.g. a date stored as string), a LongType epoch, or any non-temporal column, e.g. days('2024-01-01') or days(ts_str).
Common situations: Dates stored as strings in a column being partitioned by days(); passing an epoch bigint; using days() in a CREATE TABLE partition spec on a string column.
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 timestamp: ${valueType.catalogString()}
- Expected value to be date or timestamp: ${valueType.catalogS
- Expected value to be date or timestamp: ${valueType.catalogS
- Expected value to be timestamp: ${valueType.catalogString()}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/990d9587fb755c40.
Report an issue: GitHub.