apache/beam · error · ValueError

percentile should be between 0 and 1.

Error message

percentile should be between 0 and 1.

What it means

Histogram percentile queries (p50/p90/p99 via get_linear_interpolation) require a percentile in [0, 1]. Values outside this range have no defined quantile, so Beam raises ValueError before computing. Note the check rejects exactly 1 via percentile > 1, allowing 1 but the docstring recommends (0, 1).

Solutions

  1. Express percentiles as fractions: 0.5 for p50, 0.99 for p99.
  2. Clamp input: percentile = min(max(p, 0.0), 1.0).
  3. Convert user-facing percent inputs: p / 100.0 before calling.
  4. Reject invalid values at the configuration boundary.

Example fix

// before
h.get_linear_interpolation(95)  # meant 95th percentile
// after
h.get_linear_interpolation(0.95)
Defensive patterns

Strategy: validation

Validate before calling

if not (0.0 <= percentile <= 1.0):
    raise ValueError('percentile must be a fraction in [0, 1]')

Try / catch

try:
    v = h.p99(percentile=p)
except ValueError:
    v = h.p99(percentile=min(max(p, 0.0), 1.0))

Prevention

When it happens

Trigger: Calling h.p99(percentile=1.5) or get_linear_interpolation(-0.1); passing percentages (e.g. 90) instead of fractions (0.9); bad config-driven percentile values.

Common situations: Confusing percent (0-100) with fraction (0-1); NaN sneaking past comparisons and then failing downstream; user-supplied percentile parameters unvalidated.

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/ee54a41df9156c5b. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/utils/histogram.py:136

                _format(self._get_linear_interpolation(0.90)),
                _format(self._get_linear_interpolation(0.50))))
      else:
        return ('Total count: %s' % (self.total_count(), ))

  def get_linear_interpolation(self, percentile):
    """Calculate percentile estimation based on linear interpolation.

    It first finds the bucket which includes the target percentile and
    projects the estimated point in the bucket by assuming all the elements
    in the bucket are uniformly distributed.

    Args:
      percentile: The target percentile of the value returning from this
        method. Should be a floating point number greater than 0 and less
        than 1.
    """
    if percentile > 1 or percentile < 0:
      raise ValueError('percentile should be between 0 and 1.')
    with self._lock:
      return self._get_linear_interpolation(percentile)

  def _get_linear_interpolation(self, percentile):
    total_num_records = self.total_count()
    if total_num_records == 0:
      raise RuntimeError('histogram has no record.')

    index = 0
    record_sum = self._num_bot_records
    if record_sum / total_num_records >= percentile:
      return float('-inf')
    while index < self._bucket_type.num_buckets():
      record_sum += self._buckets.get(index, 0)
      if record_sum / total_num_records >= percentile:
        break
      index += 1
    if index == self._bucket_type.num_buckets():

View on GitHub (pinned to 12126d8942)