apache/iceberg · error · IcebergParseException

Invalid transform argument

Error message

Invalid transform argument

What it means

In transform/argument visiting (e.g. for partition-field specs), the builder expects either a column reference or a constant literal. If neither parses out of the context, it throws an IcebergParseException with this generic message, meaning the transform argument is missing or unparseable.

Solutions

  1. Provide a column name inside the transform, e.g. `bucket(16, col)`.
  2. Or provide a literal where literals are accepted (e.g. truncate width) instead of an expression.
  3. Remove invalid expressions — Iceberg transforms accept identifiers/constants only, not arbitrary expressions.
  4. Check for stray characters or missing arguments caused by string interpolation.

Example fix

-- before
ALTER TABLE t ADD PARTITION FIELD bucket(16, year(ts))
-- after
ALTER TABLE t ADD PARTITION FIELD bucket(16, ts)  -- transform arg must be a column, not a nested expression
Defensive patterns

Strategy: validation

Validate before calling

// check the transform argument resolves to a column or literal before building SQL
// good: bucket(16, ts), truncate(10, name), days(ts)
// bad: bucket(16, year(ts)), bucket(16, )

Prevention

When it happens

Trigger: Statements like `ALTER TABLE t ADD PARTITION FIELD bucket(...)` where the argument is neither a column nor a literal — e.g. empty parentheses, a non-column expression, or a malformed token.

Common situations: Truncated SQL, passing a SQL expression (e.g. a function call or arithmetic) where Iceberg only accepts a column or literal, or quoting errors making the parser fail to see a reference.

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


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

Appendix: source

Thrown at spark/v4.1/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)