{"record":{"id":"80a3ba5106de371a","repo":"prometheus/prometheus","slug":"only-one-bucket-in-histogram-0-0-cannot-cal","errorCode":null,"errorMessage":"Only one bucket in histogram ([-0, 0]). Cannot calculate defaultExpBucketWidth.","messagePattern":"Only one bucket in histogram \\(\\[-0, 0\\]\\)\\. Cannot calculate defaultExpBucketWidth\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web/ui/mantine-ui/src/pages/query/HistogramHelpers.ts","lineNumber":14,"sourceCode":"// Calculates a default width of exponential histogram bucket ranges. If the last bucket is [0, 0],\n// the width is calculated using the second to last bucket. returns error if the last bucket is [-0, 0],\nexport function calculateDefaultExpBucketWidth(\n  last: [number, string, string, string],\n  buckets: [number, string, string, string][]\n): number {\n  if (parseFloat(last[2]) === 0 || parseFloat(last[1]) === 0) {\n    if (buckets.length > 1) {\n      return Math.abs(\n        Math.log(Math.abs(parseFloat(buckets[buckets.length - 2][2]))) -\n          Math.log(Math.abs(parseFloat(buckets[buckets.length - 2][1])))\n      );\n    } else {\n      throw new Error(\n        \"Only one bucket in histogram ([-0, 0]). Cannot calculate defaultExpBucketWidth.\"\n      );\n    }\n  } else {\n    return Math.abs(\n      Math.log(Math.abs(parseFloat(last[2]))) -\n        Math.log(Math.abs(parseFloat(last[1])))\n    );\n  }\n}\n\n// Finds the lowest positive value from the bucket ranges\n// Returns 0 if no positive values are found or if there are no buckets.\nexport function findMinPositive(buckets: [number, string, string, string][]) {\n  if (!buckets || buckets.length === 0) {\n    return 0; // no buckets\n  }\n  for (let i = 0; i < buckets.length; i++) {","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/prometheus/prometheus/blob/44d6a0e0b1dbdcba4e68853d50e0bafc87d90507/web/ui/mantine-ui/src/pages/query/HistogramHelpers.ts#L1-L32","documentation":"calculateDefaultExpBucketWidth computes the default log-scale bucket width for native histograms in the mantine-ui query page. When the last (rightmost) bucket's upper or lower bound parses as 0 — the [-0, 0] sentinel bucket Prometheus emits for underflow/overflow counts — it falls back to the second-to-last bucket. If that was the ONLY bucket, there is no interval to derive a width from, so it throws.","triggerScenarios":"A classic-histogram query result whose bucket array is exactly [['<ts>','-0','0','<count>']] — a single [-0,0] bucket. Real native histogram data always has multiple buckets, so this indicates degenerate or synthetic data.","commonSituations":"Test fixtures or mocked responses with a single zero-width bucket; scraped metrics exposing a histogram with no finite buckets; hand-crafted histogram samples during development.","solutions":["Inspect the query result's buckets array to confirm the shape.","Emit real histogram data (multiple bucket boundaries) from the source metric.","If writing tests, use bucket arrays matching production shape (more than one finite bucket).","Callers can catch this and fall back to a default width constant."],"exampleFix":"// before\nconst width = calculateDefaultExpBucketWidth(buckets[buckets.length-1], buckets);\n\n// after\ntry {\n  const width = calculateDefaultExpBucketWidth(buckets[buckets.length-1], buckets);\n} catch {\n  const width = 1; // sensible default for degenerate single-bucket data\n}","handlingStrategy":"try-catch","validationCode":"const hasFiniteBucket = (b: [number, string, string, string][]) =>\n  b.length > 1 || (parseFloat(b[0][1]) !== 0 && parseFloat(b[0][2]) !== 0);\nif (!hasFiniteBucket(buckets)) skipHistogramPanel();","typeGuard":"function isDerivableHistogram(buckets: [number, string, string, string][]): boolean {\n  if (buckets.length === 0) return false;\n  const last = buckets[buckets.length - 1];\n  return buckets.length > 1 || (parseFloat(last[1]) !== 0 && parseFloat(last[2]) !== 0);\n}","tryCatchPattern":"try {\n  width = calculateDefaultExpBucketWidth(last, buckets);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('Only one bucket')) {\n    width = 1; // fallback default\n  } else throw err;\n}","preventionTips":["Validate bucket arrays before computing widths in custom visualizations.","Keep test fixtures shaped like real Prometheus histogram responses (multiple finite buckets).","Instrument metrics sources to alert on degenerate single-bucket histograms."],"tags":["histogram","native-histogram","mantine-ui","data-validation"],"backgroundTag":null,"analyzedSha":"44d6a0e0b1dbdcba4e68853d50e0bafc87d90507","analyzedAt":"2026-08-15T08:44:33.427Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}