apache/iceberg · error · UnsupportedOperationException
Expected value to be date or timestamp: ${valueType.catalogS
Error message
Expected value to be date or timestamp: ${valueType.catalogString()} What it means
The months() SQL catalog function only accepts date or timestamp (incl. timestamp_ntz) values. Binding with any other value type throws UnsupportedOperationException including the actual type via catalogString().
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/functions/MonthsFunction.java:46
import org.apache.spark.sql.types.TimestampType;
/**
* A Spark function implementation for the Iceberg month transform.
*
* <p>Example usage: {@code SELECT system.months('source_col')}.
*/
public class MonthsFunction extends UnaryUnboundFunction {
@Override
protected BoundFunction doBind(DataType valueType) {
if (valueType instanceof DateType) {
return new DateToMonthsFunction();
} else if (valueType instanceof TimestampType) {
return new TimestampToMonthsFunction();
} else if (valueType instanceof TimestampNTZType) {
return new TimestampNtzToMonthsFunction();
} else {
throw new UnsupportedOperationException(
"Expected value to be date or timestamp: " + valueType.catalogString());
}
}
@Override
public String description() {
return name()
+ "(col) - Call Iceberg's month transform\n"
+ " col :: source column (must be date or timestamp)";
}
@Override
public String name() {
return "months";
}
private abstract static class BaseToMonthsFunction extends BaseScalarFunction<Integer> {
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Cast the value: system.months(CAST(ts_str AS TIMESTAMP)) or system.months(CAST(d AS DATE))
- Convert numeric epochs with timestamp_millis()/timestamp_micros() before months()
- Use the months() only for temporal columns; otherwise use month() extraction functions
Example fix
// before
spark.sql("SELECT system.months('2024-03-15')")
// after
spark.sql("SELECT system.months(CAST('2024-03-15' AS DATE))") Defensive patterns
Strategy: type-guard
Validate before calling
// months() accepts date/timestamp only
boolean monthsOk(DataType t) { return t instanceof DateType || t instanceof TimestampType || t instanceof TimestampNTZType; } Type guard
boolean monthsOk(DataType t) { return t instanceof DateType || t instanceof TimestampType || t instanceof TimestampNTZType; } Prevention
- CAST string/numeric inputs to DATE or TIMESTAMP before months()
- Use Spark's month() for plain extraction instead of the transform function when types don't fit
- Validate schemas in SQL-generating code paths
When it happens
Trigger: Calling system.months(value) where value is a string, long, decimal, or other non-date/timestamp type.
Common situations: Passing string dates without CAST; passing epoch values; passing an int year-month number expecting month extraction.
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 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/97f0316ce9ea5660.
Report an issue: GitHub.