{"record":{"id":"06661f150066a346","repo":"apache/iceberg","slug":"wrong-number-of-inputs-expected-numbuckets-and-va-06661f","errorCode":null,"errorMessage":"Wrong number of inputs (expected numBuckets and value)","messagePattern":"Wrong number of inputs \\(expected numBuckets and value\\)","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/functions/BucketFunction.java","lineNumber":71,"sourceCode":" * <p>Example usage: {@code SELECT system.bucket(128, 'abc')}, which returns the bucket 122.\n *\n * <p>Note that for performance reasons, the given input number of buckets is not validated in the\n * implementations used in code-gen. The number of buckets must be positive to give meaningful\n * results.\n */\npublic class BucketFunction implements UnboundFunction {\n\n  private static final int NUM_BUCKETS_ORDINAL = 0;\n  private static final int VALUE_ORDINAL = 1;\n\n  private static final Set<DataType> SUPPORTED_NUM_BUCKETS_TYPES =\n      ImmutableSet.of(DataTypes.ByteType, DataTypes.ShortType, DataTypes.IntegerType);\n\n  @Override\n  @SuppressWarnings(\"checkstyle:CyclomaticComplexity\")\n  public BoundFunction bind(StructType inputType) {\n    if (inputType.size() != 2) {\n      throw new UnsupportedOperationException(\n          \"Wrong number of inputs (expected numBuckets and value)\");\n    }\n\n    StructField numBucketsField = inputType.fields()[NUM_BUCKETS_ORDINAL];\n    StructField valueField = inputType.fields()[VALUE_ORDINAL];\n\n    if (!SUPPORTED_NUM_BUCKETS_TYPES.contains(numBucketsField.dataType())) {\n      throw new UnsupportedOperationException(\n          \"Expected number of buckets to be tinyint, shortint or int\");\n    }\n\n    DataType type = valueField.dataType();\n    if (type instanceof DateType) {\n      return new BucketInt(type);\n    } else if (type instanceof ByteType\n        || type instanceof ShortType\n        || type instanceof IntegerType) {\n      return new BucketInt(DataTypes.IntegerType);","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/functions/BucketFunction.java#L53-L89","documentation":"BucketFunction implements Iceberg's bucket(size, value) SQL function for Spark. bind() validates the input signature: it requires exactly two arguments — numBuckets (integer type) and the value to bucket. Any call with a different argument count is rejected with UnsupportedOperationException before type checking.","triggerScenarios":"Invoking bucket() via Spark SQL or the catalog function interface with an argument count other than 2 — e.g. bucket(8) missing the value, bucket(8, col, extra), or SQL that mis-parses a nested call into multiple inputs.","commonSituations":"Hand-writing bucket() expressions for partition transforms; defining partitioned tables with a malformed transform spec; IDE/SQL autocompletion producing wrong arity; calling the function through engine code that flattens arguments incorrectly.","solutions":["Call bucket with exactly two arguments: bucket(numBuckets, value), e.g. bucket(8, user_id).","If used in a partition spec, verify the transform syntax: PARTITIONED BY (bucket(8, user_id)).","Check for accidental extra arguments from expression composition or string interpolation in generated SQL.","Ensure the first argument is a literal integer (numBuckets) and only the second is the value column."],"exampleFix":"// before\nfunctions.call(\"bucket\", lit(8)) // one argument\n// after\nfunctions.call(\"bucket\", lit(8), col(\"user_id\")) // numBuckets + value","handlingStrategy":"validation","validationCode":"if (args == null || args.length != 2) {\n  throw new IllegalArgumentException(\"bucket() requires exactly 2 arguments: bucket(numBuckets, value)\");\n}","typeGuard":"static boolean validBucketArgs(Expression[] args) {\n  return args != null && args.length == 2 && args[0] instanceof Literal;\n}","tryCatchPattern":"try {\n  bound = bucketFn.bind(inputType);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"Wrong number of inputs\")) {\n    throw new AnalysisException(\"Use bucket(numBuckets, value) with exactly two arguments\");\n  } else throw e;\n}","preventionTips":["Always call bucket as bucket(<int literal>, <column>).","Use catalog DDL syntax (PARTITIONED BY (bucket(8, col))) rather than composing the function manually.","Add argument-count validation before invoking catalog function bindings in generated SQL."],"tags":["spark","sql-functions","bucket-transform","argument-count"],"backgroundTag":"missing-required-argument","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}