apache/iceberg · error · UnsupportedOperationException
Expected truncation width to be tinyint, shortint or int
Error message
Expected truncation width to be tinyint, shortint or int
What it means
Iceberg's truncate function requires the width argument to be an integral type: tinyint (byte), shortint (short), or int. bind() throws this UnsupportedOperationException when the first argument is any other type (e.g. string, bigint, long literal).
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/functions/TruncateFunction.java:72
public class TruncateFunction implements UnboundFunction {
private static final int WIDTH_ORDINAL = 0;
private static final int VALUE_ORDINAL = 1;
private static final Set<DataType> SUPPORTED_WIDTH_TYPES =
ImmutableSet.of(DataTypes.ByteType, DataTypes.ShortType, DataTypes.IntegerType);
@Override
public BoundFunction bind(StructType inputType) {
if (inputType.size() != 2) {
throw new UnsupportedOperationException("Wrong number of inputs (expected width and value)");
}
StructField widthField = inputType.fields()[WIDTH_ORDINAL];
StructField valueField = inputType.fields()[VALUE_ORDINAL];
if (!SUPPORTED_WIDTH_TYPES.contains(widthField.dataType())) {
throw new UnsupportedOperationException(
"Expected truncation width to be tinyint, shortint or int");
}
DataType valueType = valueField.dataType();
if (valueType instanceof ByteType) {
return new TruncateTinyInt();
} else if (valueType instanceof ShortType) {
return new TruncateSmallInt();
} else if (valueType instanceof IntegerType) {
return new TruncateInt();
} else if (valueType instanceof LongType) {
return new TruncateBigInt();
} else if (valueType instanceof DecimalType) {
return new TruncateDecimal(
((DecimalType) valueType).precision(), ((DecimalType) valueType).scale());
} else if (valueType instanceof StringType) {
return new TruncateString();
} else if (valueType instanceof BinaryType) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Cast the width to INT: truncate(CAST(10 AS INT), col)
- Use a plain integer literal, e.g. truncate(10, col)
- If width is stored as bigint/string, coerce it with CAST or try_cast before calling truncate
Example fix
// before SELECT truncate(width_col, some_col) FROM t; -- width_col is BIGINT // after SELECT truncate(CAST(width_col AS INT), some_col) FROM t;
Defensive patterns
Strategy: validation
Validate before calling
// ensure width is integral val widthType = StringType etc; require(Seq(ByteType, ShortType, IntegerType).contains(widthExpr.dataType), "width must be tinyint/short/int")
Type guard
def isIntegralWidth(t: DataType): Boolean = t match { case _: ByteType | _: ShortType | _: IntegerType => true; case _ => false } Try / catch
try { ... } catch { case e: UnsupportedOperationException if e.getMessage.contains("truncation width") => ... } Prevention
- Use plain integer literals for width
- CAST non-int widths to INT before the call
- Avoid passing width columns of BIGINT or STRING type
When it happens
Trigger: Passing a width that is a string ('10'), a long/bigint (10L), decimal, or a column of non-integral type as the first argument to truncate().
Common situations: Passing width as a string literal from templated SQL; using a BIGINT column or parameter as width; Spark inferring an integer literal as bigint in some contexts.
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:
- Wrong number of inputs (expected width and value)
- Expected truncation col to be tinyint, shortint, int, bigint
- Wrong number of inputs (expected value)
- Expected value to be date or timestamp: ${valueType.catalogS
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ea332b7e5e040f9c.
Report an issue: GitHub.