apache/beam · error · ValueError

number of hash buckets must be positive, got

Error message

number of hash buckets must be positive, got 

What it means

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.

Solutions

  1. Pass a positive integer for hash_buckets (e.g. hash_buckets=1000).
  2. Check the value feeding hash_buckets; ensure defaults/CLI parsing do not yield 0 or negative values.
  3. Add a validation/assert before constructing the transform.

Example fix

# before
HashBuckets(columns=['user_id'], hash_buckets=0)
# after
HashBuckets(columns=['user_id'], hash_buckets=10000)
Defensive patterns

Strategy: validation

Validate before calling

assert isinstance(hash_buckets, int) and hash_buckets > 0, f'hash_buckets must be positive, got {hash_buckets}'

Type guard

def valid_buckets(n) -> bool:
    return isinstance(n, int) and not isinstance(n, bool) and n > 0

Try / catch

try:
    t = HashBuckets(columns=cols, hash_buckets=n)
except ValueError as e:
    raise ConfigError(f'invalid hash_buckets: {n}') from e

Prevention

When it happens

Trigger: Calling tft.Scale/hash-bucket transform (class HashBuckets) with hash_buckets=0 or hash_buckets<1, e.g. HashBuckets(columns=['x'], hash_buckets=0).

Common situations: 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.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/49c9ea9b2eefc443. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/ml/transforms/tft.py:709

    '''Hashes strings into the provided number of buckets.
    
    Args:
      columns: A list of the column names to apply the transformation on.
      hash_buckets: the number of buckets to hash the strings into.
      key: optional. An array of two Python `uint64`. If passed, output will be
        a deterministic function of `strings` and `key`. Note that hashing will
        be slower if this value is specified.
      name: optional. A name for this operation.

    Raises:
      ValueError if `hash_buckets` is not a positive and non-zero integer.
    '''
    self.hash_buckets = hash_buckets
    self.key = key
    self.name = name

    if hash_buckets < 1:
      raise ValueError(
          'number of hash buckets must be positive, got ', hash_buckets)

    super().__init__(columns)

  def apply_transform(
      self, data: common_types.TensorType,
      output_col_name: str) -> dict[str, common_types.TensorType]:
    output_dict = {
        output_col_name: tft.hash_strings(
            strings=data,
            hash_buckets=self.hash_buckets,
            key=self.key,
            name=self.name)
    }
    return output_dict


@register_input_dtype(str)

View on GitHub (pinned to 12126d8942)