{"record":{"id":"77f2711e4ae43452","repo":"apache/beam","slug":"input-should-not-be-nan-or-infinite","errorCode":null,"errorMessage":"input should not be NaN or infinite.","messagePattern":"input should not be NaN or infinite\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/combiners/src/main/java/org/apache/beam/sdk/extensions/combiners/Histogram.java","lineNumber":335,"sourceCode":"          ArrayUtils.toPrimitive(bucketBounds.getBounds().toArray(new Double[0])),\n          bucketBounds.getBoundsInclusivity());\n    }\n\n    @Override\n    public HistogramAccumulator createAccumulator() {\n      return new HistogramAccumulator(bounds.length + 1);\n    }\n\n    @Override\n    public HistogramAccumulator addInput(HistogramAccumulator accumulator, T input)\n        throws IllegalArgumentException {\n      if (input == null) {\n        throw new NullPointerException(\"input should not be null.\");\n      }\n\n      Double inputDoubleValue = ((Number) input).doubleValue();\n      if (inputDoubleValue.isNaN() || inputDoubleValue.isInfinite()) {\n        throw new IllegalArgumentException(\"input should not be NaN or infinite.\");\n      }\n      int index = Arrays.binarySearch(bounds, inputDoubleValue);\n      if (index < 0) {\n        accumulator.counts[-index - 1]++;\n      } else {\n        // This means the value is on bound, can be handled based on the bound inclusivity.\n        if (boundsInclusivity == BoundsInclusivity.LOWER_BOUND_INCLUSIVE_UPPER_BOUND_EXCLUSIVE) {\n          accumulator.counts[index + 1]++;\n        } else {\n          accumulator.counts[index]++;\n        }\n      }\n      return accumulator;\n    }\n\n    @Override\n    public HistogramAccumulator mergeAccumulators(Iterable<HistogramAccumulator> accumulators) {\n      Iterator<HistogramAccumulator> iter = accumulators.iterator();","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/combiners/src/main/java/org/apache/beam/sdk/extensions/combiners/Histogram.java#L317-L353","documentation":"Histogram addInput rejects input values that are NaN or infinite, since they cannot be placed in any finite bucket and would corrupt the histogram counts. The input is converted to double via ((Number) input).doubleValue() and checked before the binarySearch into the bounds array.","triggerScenarios":"Feeding the Histogram combiner values produced by division by zero, sqrt of a negative number (NaN), overflowing arithmetic, or parsing of 'Infinity'/'NaN' strings; calling addInput(accumulator, Double.NaN) directly.","commonSituations":"Computing rates/ratios with zero denominators; sensor data with missing readings encoded as NaN/Infinity; deserializing JSON that contains Infinity; averaging empty windows.","solutions":["Filter out NaN/infinite values before the transform: Filter.by(x -> Double.isFinite(((Number) x).doubleValue())).","Fix the upstream math (guard denominators, clamp results) so finite values are produced.","Sanitize at ingestion: map NaN/Infinity to a sentinel or drop them with a DoFn.","If Infinity is meaningful, widen bucket bounds and clamp values to the last bound instead of passing raw Infinity."],"exampleFix":"// before\npcollection.apply(Histogram.globally(...));\n// after\npcollection.apply(Filter.by(x -> Double.isFinite(((Number) x).doubleValue())))\n           .apply(Histogram.globally(...));","handlingStrategy":"validation","validationCode":"double d = ((Number) value).doubleValue();\nif (Double.isNaN(d) || Double.isInfinite(d)) {\n  value = clampOrDefault(d); // e.g. skip, or clamp to last bound\n}","typeGuard":"boolean isFiniteNumber(T v) {\n  return v instanceof Number && Double.isFinite(((Number) v).doubleValue());\n}","tryCatchPattern":"try {\n  histogramFn.addInput(accumulator, value);\n} catch (IllegalArgumentException e) {\n  LOG.warn(\"dropping non-finite histogram input\", e);\n}","preventionTips":["Guard divisions (ratios, rates) against zero denominators.","Sanitize sensor/ingested data where NaN/Infinity encode missing readings.","Clamp extreme values to the outermost bucket instead of passing Infinity."],"tags":["java","illegal-argument","nan","numeric","histogram"],"backgroundTag":"invalid-argument-value","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"}