apache/iceberg · error · java.lang.IllegalArgumentException
Cannot find width for transform: <transform.describe()>
Error message
Cannot find width for transform: <transform.describe()>
What it means
findWidth extracts the width parameter (N for truncate) from a Spark truncate transform's literal argument. If the transform's parameters do not contain an integer Literal of the expected shape, it throws IllegalArgumentException because no width can be determined for the truncate spec.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:504
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)
Solutions
- Provide a constant integer width: truncate(W, col) with W a literal integer
- Replace non-literal width expressions with their computed constant value in the DDL
- Validate the transform's parameters before conversion
Example fix
// before PARTITIONED BY (truncate(width_col, data)); // after PARTITIONED BY (truncate(10, data));
Defensive patterns
Strategy: validation
Validate before calling
// ensure the truncate transform's width is a literal integer before conversion
Object[] params = transform.parameters();
if (params.length == 0 || !(params[0] instanceof Literal)
|| !(((Literal<?>) params[0]).value() instanceof Integer)) {
throw new IllegalArgumentException("truncate requires a constant integer width");
} Try / catch
try {
Spark3Util.toPartitionSpec(schema, transforms);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Cannot find width")) {
// prompt user to supply a constant width
}
} Prevention
- Always write truncate with a literal integer width
- Ban non-constant expressions in partition transform parameters
- Validate DDL transforms before submitting
When it happens
Trigger: A truncate transform whose parameter is missing, non-literal, or not an integer literal (e.g. truncate(noW, col) or a non-constant expression) reaching findWidth via toPartitionSpec or sort conversion.
Common situations: Non-constant width expressions in DDL (variables/functions); typos or wrong argument order in truncate(); SQL generators emitting symbolic widths.
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: %s
- Cannot truncate type: + type
- apply(value) is deprecated, use bind(Type).apply(value)
- Transform is not supported: ${transform}
- Transform is not supported:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ab32a3a7a4f21d19.
Report an issue: GitHub.