{"record":{"id":"b0c1549ad3803da9","repo":"apache/iceberg","slug":"invalid-transform-argument-b0c154","errorCode":null,"errorMessage":"Invalid transform argument","messagePattern":"Invalid transform argument","errorType":"exception","errorClass":"IcebergParseException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSqlExtensionsAstBuilder.scala","lineNumber":315,"sourceCode":"  override def visitApplyTransform(ctx: ApplyTransformContext): Transform = withOrigin(ctx) {\n    val args = toSeq(ctx.arguments).map(typedVisit[expressions.Expression])\n    ApplyTransform(ctx.transformName.getText, args)\n  }\n\n  /**\n   * Create a transform argument from a column reference or a constant.\n   */\n  override def visitTransformArgument(ctx: TransformArgumentContext): expressions.Expression =\n    withOrigin(ctx) {\n      val reference = Option(ctx.multipartIdentifier())\n        .map(typedVisit[Seq[String]])\n        .map(FieldReference(_))\n      val literal = Option(ctx.constant)\n        .map(visitConstant)\n        .map(lit => LiteralValue(lit.value, lit.dataType))\n      reference\n        .orElse(literal)\n        .getOrElse(throw new IcebergParseException(s\"Invalid transform argument\", ctx))\n    }\n\n  /**\n   * Return a multi-part identifier as Seq[String].\n   */\n  override def visitMultipartIdentifier(ctx: MultipartIdentifierContext): Seq[String] =\n    withOrigin(ctx) {\n      toSeq(ctx.parts).map(_.getText)\n    }\n\n  override def visitSingleOrder(ctx: SingleOrderContext): Seq[(Term, SortDirection, NullOrder)] =\n    withOrigin(ctx) {\n      toSeq(ctx.order.fields).map(typedVisit[(Term, SortDirection, NullOrder)])\n    }\n\n  override def visitSingleStatement(ctx: SingleStatementContext): LogicalPlan = withOrigin(ctx) {\n    visit(ctx.statement).asInstanceOf[LogicalPlan]\n  }","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSqlExtensionsAstBuilder.scala#L297-L333","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Provide a column name inside the transform, e.g. `bucket(16, col)`.","Or provide a literal where literals are accepted (e.g. truncate width) instead of an expression.","Remove invalid expressions — Iceberg transforms accept identifiers/constants only, not arbitrary expressions.","Check for stray characters or missing arguments caused by string interpolation."],"exampleFix":"-- before\nALTER TABLE t ADD PARTITION FIELD bucket(16, year(ts))\n-- after\nALTER TABLE t ADD PARTITION FIELD bucket(16, ts)  -- transform arg must be a column, not a nested expression","handlingStrategy":"validation","validationCode":"// check the transform argument resolves to a column or literal before building SQL\n// good: bucket(16, ts), truncate(10, name), days(ts)\n// bad: bucket(16, year(ts)), bucket(16, )","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only pass column identifiers or literals inside Iceberg transforms.","Never nest expressions (functions/arithmetic) in transform arguments.","Validate interpolated SQL fragments are non-empty and well-formed."],"tags":["spark-sql","parser","transform","partition-field"],"backgroundTag":"invalid-argument-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}