apache/iceberg · error · IcebergParseException
Invalid transform argument
Error message
Invalid transform argument
What it means
When building a transform from the grammar (e.g. bucket[N](col), truncate[L](col), year/month/day/hour(col) or a literal argument), the builder expects the argument to be either a column reference or a constant literal; if ctx has neither (or both parse to nothing), it throws IcebergParseException "Invalid transform argument".
Source
Thrown at spark/v4.2/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSqlExtensionsAstBuilder.scala:315
override def visitApplyTransform(ctx: ApplyTransformContext): Transform = withOrigin(ctx) {
val args = toSeq(ctx.arguments).map(typedVisit[expressions.Expression])
ApplyTransform(ctx.transformName.getText, args)
}
/**
* Create a transform argument from a column reference or a constant.
*/
override def visitTransformArgument(ctx: TransformArgumentContext): expressions.Expression =
withOrigin(ctx) {
val reference = Option(ctx.multipartIdentifier())
.map(typedVisit[Seq[String]])
.map(FieldReference(_))
val literal = Option(ctx.constant)
.map(visitConstant)
.map(lit => LiteralValue(lit.value, lit.dataType))
reference
.orElse(literal)
.getOrElse(throw new IcebergParseException(s"Invalid transform argument", ctx))
}
/**
* Return a multi-part identifier as Seq[String].
*/
override def visitMultipartIdentifier(ctx: MultipartIdentifierContext): Seq[String] =
withOrigin(ctx) {
toSeq(ctx.parts).map(_.getText)
}
override def visitSingleOrder(ctx: SingleOrderContext): Seq[(Term, SortDirection, NullOrder)] =
withOrigin(ctx) {
toSeq(ctx.order.fields).map(typedVisit[(Term, SortDirection, NullOrder)])
}
override def visitSingleStatement(ctx: SingleStatementContext): LogicalPlan = withOrigin(ctx) {
visit(ctx.statement).asInstanceOf[LogicalPlan]
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Supply a column reference as the argument: `bucket(16)(col)` / `truncate(10)(col)`.
- Or supply a constant literal where the transform accepts one, e.g. identity-like positional references in CALL procedures.
- Remove complex expressions; precompute the value or add a column to the table instead.
- Check the statement against the Iceberg transform grammar (bucket[N], truncate[L], year, month, day, hour, identity).
Example fix
-- before ALTER TABLE t ADD PARTITION FIELD days(a + b) AS d -- after ALTER TABLE t ADD PARTITION FIELD days(event_ts) AS d
Defensive patterns
Strategy: validation
Validate before calling
// Validate transform argument is a bare column or literal before submitting
val transform = s"$name($arg)"
val valid = arg.matches("[A-Za-z_][A-Za-z0-9_.]*") || arg.matches("-?\\d+")
require(valid, s"Transform argument must be a column reference or literal: $transform") Try / catch
try { spark.sql(stmt) } catch {
case e: IcebergParseException if e.getMessage.contains("Invalid transform argument") =>
throw new IllegalArgumentException(s"Fix transform to e.g. $name(col)", e)
} Prevention
- Always pass a plain column name or literal to bucket/truncate/year/month/day/hour transforms
- Precompute complex expressions into a table column before partitioning by them
- Check transform syntax against Iceberg docs when generating partition DDL programmatically
When it happens
Trigger: Writing a transform with a missing or malformed argument, e.g. `bucket(4)()`, `truncate[]`, an expression that is neither a column nor a literal such as `bucket(4)(a + b)`, or an empty argument in a procedure/DDL transform position.
Common situations: Typos in partition-evolution DDL like `ALTER TABLE t ADD PARTITION FIELD bucket(16)()`; programmatic SQL generation emitting empty transform arguments; using complex expressions where only identifiers or literals are accepted.
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
- Unable to parse sortOrder: %s
- Cannot pass path based identifier to %s method. %s is a path
- Invalid session catalog: sparkSessionCatalog
- Cannot pass path based identifier to %s method. %s is a path
- unsupported strategy: + strategy + . Only binpack or sort is
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8265ec811bbeb910.
Report an issue: GitHub.