{"record":{"id":"49c9ea9b2eefc443","repo":"apache/beam","slug":"number-of-hash-buckets-must-be-positive-got","errorCode":null,"errorMessage":"number of hash buckets must be positive, got ","messagePattern":"number of hash buckets must be positive, got ","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/ml/transforms/tft.py","lineNumber":709,"sourceCode":"    '''Hashes strings into the provided number of buckets.\n    \n    Args:\n      columns: A list of the column names to apply the transformation on.\n      hash_buckets: the number of buckets to hash the strings into.\n      key: optional. An array of two Python `uint64`. If passed, output will be\n        a deterministic function of `strings` and `key`. Note that hashing will\n        be slower if this value is specified.\n      name: optional. A name for this operation.\n\n    Raises:\n      ValueError if `hash_buckets` is not a positive and non-zero integer.\n    '''\n    self.hash_buckets = hash_buckets\n    self.key = key\n    self.name = name\n\n    if hash_buckets < 1:\n      raise ValueError(\n          'number of hash buckets must be positive, got ', hash_buckets)\n\n    super().__init__(columns)\n\n  def apply_transform(\n      self, data: common_types.TensorType,\n      output_col_name: str) -> dict[str, common_types.TensorType]:\n    output_dict = {\n        output_col_name: tft.hash_strings(\n            strings=data,\n            hash_buckets=self.hash_buckets,\n            key=self.key,\n            name=self.name)\n    }\n    return output_dict\n\n\n@register_input_dtype(str)","sourceCodeStart":691,"sourceCodeEnd":727,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/ml/transforms/tft.py#L691-L727","documentation":"HashBuckets in Apache Beam's ML transforms requires the number of hash buckets to be at least 1. The __init__ validates hash_buckets and raises ValueError when it is less than 1. Passing 0 or a negative count would make bucketing via modulo meaningless.","triggerScenarios":"Calling tft.Scale/hash-bucket transform (class HashBuckets) with hash_buckets=0 or hash_buckets<1, e.g. HashBuckets(columns=['x'], hash_buckets=0).","commonSituations":"Computing the bucket count from a config or CLI flag that defaulted to 0, or a user confusing 'hash buckets' with 'number of keys' and passing 0.","solutions":["Pass a positive integer for hash_buckets (e.g. hash_buckets=1000).","Check the value feeding hash_buckets; ensure defaults/CLI parsing do not yield 0 or negative values.","Add a validation/assert before constructing the transform."],"exampleFix":"# before\nHashBuckets(columns=['user_id'], hash_buckets=0)\n# after\nHashBuckets(columns=['user_id'], hash_buckets=10000)","handlingStrategy":"validation","validationCode":"assert isinstance(hash_buckets, int) and hash_buckets > 0, f'hash_buckets must be positive, got {hash_buckets}'","typeGuard":"def valid_buckets(n) -> bool:\n    return isinstance(n, int) and not isinstance(n, bool) and n > 0","tryCatchPattern":"try:\n    t = HashBuckets(columns=cols, hash_buckets=n)\nexcept ValueError as e:\n    raise ConfigError(f'invalid hash_buckets: {n}') from e","preventionTips":["Never default hash_buckets to 0; use a sensible positive default.","Validate CLI/config-sourced bucket counts at load time."],"tags":["apache-beam","python","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}