apache/iceberg · error · IllegalArgumentException
Cannot find width for transform:
Error message
Cannot find width for transform:
What it means
findWidth can only read widths from Integer or Long literals attached to a Spark truncate transform. If the expression is any other shape (non-literal, other numeric types, casts), it throws IllegalArgumentException 'Cannot find width for transform'.
Solutions
- Pass the width as an integer literal: truncate(10, col)
- Cast or inline the width value directly in the DDL/code rather than referencing a column or config expression
- If building transforms programmatically, use Literal.create(10, DataTypes.IntegerType)
Example fix
// before Transforms.truncate(widthStr, col) // widthStr is "10" // after Transforms.truncate(Integer.parseInt(widthStr), col) // ensure > 0 and < Integer.MAX_VALUE
Defensive patterns
Strategy: validation
Validate before calling
if (!(expr instanceof org.apache.spark.sql.catalyst.expressions.Literal)) {
throw new IllegalArgumentException("truncate width must be a literal: " + expr);
} Type guard
boolean isIntOrLongLiteral(org.apache.spark.sql.catalyst.expressions.Expression e) {
return e instanceof org.apache.spark.sql.catalyst.expressions.Literal
&& (((Literal<?>) e).dataType() instanceof IntegerType
|| ((Literal<?>) e).dataType() instanceof LongType);
} Try / catch
try {
int width = findWidth(transform);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("truncate() requires an integer literal width", e);
} Prevention
- Always pass the width as a plain integer literal in DDL
- Avoid string or column-typed width parameters
- Constant-fold programmatic widths before building the transform
When it happens
Trigger: PARTITIONED BY truncate('10', col) (string literal), truncate(colW, col) (column instead of literal), or truncate(10L * 2, col) that Spark does not fold to a literal before conversion.
Common situations: Dynamic width from a config column or non-literal expression in generated DDL; string-typed width parameters; expressions Spark didn't constant-fold.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot find width for transform
- Cannot find width for transform
- Cannot find width for transform: <transform.describe()>
- Unsupported width for transform
- Already closed files for partition:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/60d83f3ea58dc7d0.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:499
Preconditions.checkArgument(
lit.value() > 0, "Unsupported width for transform: %s", transform.describe());
return lit.value();
} else if (((Literal) expr).dataType() instanceof LongType) {
Literal<Long> lit = (Literal<Long>) expr;
Preconditions.checkArgument(
lit.value() > 0 && lit.value() < Integer.MAX_VALUE,
"Unsupported width for transform: %s",
transform.describe());
if (lit.value() > Integer.MAX_VALUE) {
throw new IllegalArgumentException();
}
return lit.value().intValue();
}
}
}
throw new IllegalArgumentException("Cannot find width for transform: " + transform.describe());
}
private static String leafName(String[] fieldNames) {
Preconditions.checkArgument(
fieldNames.length > 0, "Invalid field name: at least one name is required");
return fieldNames[fieldNames.length - 1];
}
private static String peerName(String[] fieldNames, String fieldName) {
if (fieldNames.length > 1) {
String[] peerNames = Arrays.copyOf(fieldNames, fieldNames.length);
peerNames[fieldNames.length - 1] = fieldName;
return DOT.join(peerNames);
}
return fieldName;
}
private static String parentName(String[] fieldNames) {View on GitHub (pinned to 86d9c8fc54)