apache/iceberg · error · UnsupportedOperationException

Wrong number of inputs (expected width and value)

Error message

Wrong number of inputs (expected width and value)

What it means

Iceberg's truncate() function requires exactly two inputs: a truncation width and the value column. bind() checks inputType.size() == 2 and throws UnsupportedOperationException when the argument count differs (0, 1, 3+ arguments).

Solutions

  1. Supply both arguments: truncate(10, col).
  2. For strings, the width is character count: truncate(5, name); for binary/int types it is the byte width.
  3. Count the arguments in generated SQL and fix the template.

Example fix

// before
SELECT iceberg.truncate(name) FROM t;
// after
SELECT iceberg.truncate(10, name) FROM t;
Defensive patterns

Strategy: validation

Validate before calling

-- truncate always takes exactly 2 args: width, value
SELECT iceberg.truncate(10, col) FROM t;

Prevention

When it happens

Trigger: Calling iceberg.truncate(col) with only the value (forgetting width); calling iceberg.truncate(width, col, extra); generated SQL that dropped the width argument.

Common situations: Confusing truncate() with Spark's built-in truncate string function; partially edited SQL; template engines omitting an optional parameter rendered as fewer args.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/e569a478e0008442. Report an issue: GitHub.

Appendix: source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/functions/TruncateFunction.java:65

 * A Spark function implementation for the Iceberg truncate transform.
 *
 * <p>Example usage: {@code SELECT system.truncate(1, 'abc')}, which returns the String 'a'.
 *
 * <p>Note that for performance reasons, the given input width is not validated in the
 * implementations used in code-gen. The width must remain non-negative to give meaningful results.
 */
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) {

View on GitHub (pinned to 86d9c8fc54)