{"record":{"id":"808f5c68029e035b","repo":"apache/beam","slug":"histogram-has-no-record","errorCode":null,"errorMessage":"histogram has no record.","messagePattern":"histogram has no record\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/utils/histogram.py","lineNumber":143,"sourceCode":"\n    It first finds the bucket which includes the target percentile and\n    projects the estimated point in the bucket by assuming all the elements\n    in the bucket are uniformly distributed.\n\n    Args:\n      percentile: The target percentile of the value returning from this\n        method. Should be a floating point number greater than 0 and less\n        than 1.\n    \"\"\"\n    if percentile > 1 or percentile < 0:\n      raise ValueError('percentile should be between 0 and 1.')\n    with self._lock:\n      return self._get_linear_interpolation(percentile)\n\n  def _get_linear_interpolation(self, percentile):\n    total_num_records = self.total_count()\n    if total_num_records == 0:\n      raise RuntimeError('histogram has no record.')\n\n    index = 0\n    record_sum = self._num_bot_records\n    if record_sum / total_num_records >= percentile:\n      return float('-inf')\n    while index < self._bucket_type.num_buckets():\n      record_sum += self._buckets.get(index, 0)\n      if record_sum / total_num_records >= percentile:\n        break\n      index += 1\n    if index == self._bucket_type.num_buckets():\n      return float('inf')\n\n    frac_percentile = percentile - (\n        record_sum - self._buckets[index]) / total_num_records\n    bucket_percentile = self._buckets[index] / total_num_records\n    frac_bucket_size = frac_percentile * self._bucket_type.bucket_size(\n        index) / bucket_percentile","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/utils/histogram.py#L125-L161","documentation":"Percentile interpolation is undefined on an empty histogram. When total_count() is 0, Beam's _get_linear_interpolation raises RuntimeError instead of returning a meaningless value. Reached via get_linear_interpolation/p50/p90/p99 or get_percentile_info on a histogram with no recorded data.","triggerScenarios":"Calling h.p99() before any record() calls; querying a freshly deserialized or copied empty histogram; querying after combine with two empty histograms.","commonSituations":"Metrics reported before the pipeline processed any elements; windowed/filtered pipelines where a window got zero records; unit tests instantiating Histogram without seeding data.","solutions":["Guard with h.total_count() > 0 before querying percentiles.","Return a sentinel (e.g. None or NaN) when empty in caller code.","Ensure record() is invoked for all expected elements before percentile reporting.","In tests, seed the histogram with sample records first."],"exampleFix":"// before\nlatency = h.p99()\n// after\nlatency = h.p99() if h.total_count() > 0 else None","handlingStrategy":"try-catch","validationCode":"if h.total_count() == 0:\n    percentile_value = None\nelse:\n    percentile_value = h.p99()","typeGuard":null,"tryCatchPattern":"try:\n    v = h.p99()\nexcept RuntimeError:\n    v = None  # empty histogram","preventionTips":["Check total_count() before percentile queries","Seed histograms in tests with known records","Handle empty windows explicitly in metrics aggregation code"],"tags":["python","apache-beam","histogram","empty-state"],"backgroundTag":"empty-result-set","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"}