Buggy code:
public class DerivativePipelineAggregator extends PipelineAggregator { public static final Type TYPE = new Type ( "derivative" ) ; public static final Stream STREAM = new PipelineAggregatorStreams . Stream ( ) { @ Override public DerivativePipelineAggregator readResult ( StreamInput in ) throws IOException { } } ; public static void registerStreams ( ) { } private ValueFormatter formatter ; private GapPolicy gapPolicy ; private Double xAxisUnits ; public DerivativePipelineAggregator ( ) { } public DerivativePipelineAggregator ( String name , String [ ] bucketsPaths , ValueFormatter formatter , GapPolicy gapPolicy , Long xAxisUnits , Map < String , Object > metadata ) { } @ Override public Type type ( ) { } @ Override public InternalAggregation reduce ( InternalAggregation aggregation , ReduceContext reduceContext ) { InternalHistogram histo = ( ( InternalHistogram ) ( aggregation ) ) ; List < ? extends InternalHistogram . Bucket > buckets = histo . getBuckets ( ) ; InternalHistogram . Factory < ? extends InternalHistogram . Bucket > factory = histo . getFactory ( ) ; List newBuckets = new ArrayList < > ( ) ; Long lastBucketKey = null ; Double lastBucketValue = null ; for ( InternalHistogram . Bucket bucket : buckets ) { Long thisBucketKey = resolveBucketKeyAsLong ( bucket ) ; Double thisBucketValue = BucketHelpers . resolveBucketValue ( histo , bucket , bucketsPaths ( ) [ 0 ] , gapPolicy ) ; <START_BUG> if ( lastBucketValue != null ) { <END_BUG> double gradient = thisBucketValue - lastBucketValue ; double xDiff = - 1 ; if ( ( xAxisUnits ) != null ) { xDiff = ( thisBucketKey - lastBucketKey ) // ( xAxisUnits ) ; } List < InternalAggregation > aggs = new ArrayList ( eagerTransform ( bucket . getAggregations ( ) . asList ( ) , AGGREGATION_TRANFORM_FUNCTION ) ) ; aggs . add ( new InternalDerivative ( name ( ) , gradient , xDiff , formatter , new ArrayList < PipelineAggregator > ( ) , metaData ( ) ) ) ; InternalHistogram . Bucket newBucket = factory . createBucket ( bucket . getKey ( ) , bucket . getDocCount ( ) , new org . elasticsearch . search . aggregations . InternalAggregations ( aggs ) , bucket . getKeyed ( ) , bucket . getFormatter ( ) ) ; newBuckets . add ( newBucket ) ; } else { newBuckets . add ( bucket ) ; } lastBucketKey = thisBucketKey ; lastBucketValue = thisBucketValue ; } return factory . create ( newBuckets , histo ) ; } private Long resolveBucketKeyAsLong ( InternalHistogram . Bucket bucket ) { } @ Override public void doReadFrom ( StreamInput in ) throws IOException { } @ Override public void doWriteTo ( StreamOutput out ) throws IOException { } public static class Factory extends PipelineAggregatorFactory { private final ValueFormatter formatter ; private GapPolicy gapPolicy ; private Long xAxisUnits ; public Factory ( String name , String [ ] bucketsPaths , ValueFormatter formatter , GapPolicy gapPolicy , Long xAxisUnits ) { } @ Override protected PipelineAggregator createInternal ( Map < String , Object > metaData ) throws IOException { } @ Override public void doValidate ( AggregatorFactory parent , AggregatorFactory [ ] aggFactories , List < PipelineAggregatorFactory > pipelineAggregatorFactories ) { } } }

Fix:
if ( ( lastBucketValue != null ) && ( thisBucketValue != null ) ) {