@@ -99,7 +99,10 @@ func (e *elasticsearchDataQuery) processQuery(q *Query, ms *es.MultiSearchReques
9999 processDocumentQuery (q , b , from , to , defaultTimeField )
100100 } else {
101101 // Otherwise, it is a time series query and we process it
102- processTimeSeriesQuery (q , b , from , to , defaultTimeField )
102+ err := processTimeSeriesQuery (q , b , from , to , defaultTimeField )
103+ if err != nil {
104+ return err
105+ }
103106 }
104107
105108 return nil
@@ -164,12 +167,18 @@ func (bucketAgg BucketAgg) generateSettingsForDSL() map[string]interface{} {
164167 return bucketAgg .Settings .MustMap ()
165168}
166169
167- func addDateHistogramAgg (aggBuilder es.AggBuilder , bucketAgg * BucketAgg , timeFrom , timeTo int64 , timeField string ) es.AggBuilder {
170+ func addDateHistogramAgg (aggBuilder es.AggBuilder , bucketAgg * BucketAgg , timeFrom , timeTo int64 , timeField string ) ( es.AggBuilder , error ) {
168171 // If no field is specified, use the time field
169172 field := bucketAgg .Field
170173 if field == "" {
171174 field = timeField
172175 }
176+
177+ // Validate that we have a valid field name to prevent downstream errors
178+ if field == "" {
179+ return aggBuilder , fmt .Errorf ("date_histogram aggregation '%s' has no field specified and datasource timeField is empty" , bucketAgg .ID )
180+ }
181+
173182 aggBuilder .DateHistogram (bucketAgg .ID , field , func (a * es.DateHistogramAgg , b es.AggBuilder ) {
174183 a .FixedInterval = bucketAgg .Settings .Get ("interval" ).MustString ("auto" )
175184 a .MinDocCount = bucketAgg .Settings .Get ("min_doc_count" ).MustInt (0 )
@@ -204,7 +213,7 @@ func addDateHistogramAgg(aggBuilder es.AggBuilder, bucketAgg *BucketAgg, timeFro
204213 aggBuilder = b
205214 })
206215
207- return aggBuilder
216+ return aggBuilder , nil
208217}
209218
210219func addHistogramAgg (aggBuilder es.AggBuilder , bucketAgg * BucketAgg ) es.AggBuilder {
@@ -331,6 +340,30 @@ func isQueryWithError(query *Query) error {
331340 if len (query .Metrics ) == 0 || ! (isLogsQuery (query ) || isDocumentQuery (query )) {
332341 return fmt .Errorf ("invalid query, missing metrics and aggregations" )
333342 }
343+ } else {
344+ // Validate bucket aggregations have valid fields where required
345+ for _ , bucketAgg := range query .BucketAggs {
346+ // Check which aggregation types require fields
347+ switch bucketAgg .Type {
348+ case dateHistType :
349+ // For date_histogram, field can be empty (will use timeField as fallback)
350+ // Validation will happen at query processing time
351+ continue
352+ case histogramType , termsType , geohashGridType , nestedType :
353+ // These aggregation types require a field
354+ if bucketAgg .Field == "" {
355+ return fmt .Errorf ("invalid query, bucket aggregation '%s' (type: %s) is missing required field" , bucketAgg .ID , bucketAgg .Type )
356+ }
357+ case filtersType :
358+ // Filters aggregations don't need a field
359+ continue
360+ default :
361+ // For unknown aggregation types, be conservative and require field
362+ if bucketAgg .Field == "" {
363+ return fmt .Errorf ("invalid query, bucket aggregation '%s' (type: %s) is missing required field" , bucketAgg .ID , bucketAgg .Type )
364+ }
365+ }
366+ }
334367 }
335368 return nil
336369}
@@ -380,7 +413,7 @@ func processDocumentQuery(q *Query, b *es.SearchRequestBuilder, from, to int64,
380413 b .Size (stringToIntWithDefaultValue (metric .Settings .Get ("size" ).MustString (), defaultSize ))
381414}
382415
383- func processTimeSeriesQuery (q * Query , b * es.SearchRequestBuilder , from , to int64 , defaultTimeField string ) {
416+ func processTimeSeriesQuery (q * Query , b * es.SearchRequestBuilder , from , to int64 , defaultTimeField string ) error {
384417 aggBuilder := b .Agg ()
385418 // Process buckets
386419 // iterate backwards to create aggregations bottom-down
@@ -390,7 +423,11 @@ func processTimeSeriesQuery(q *Query, b *es.SearchRequestBuilder, from, to int64
390423 )
391424 switch bucketAgg .Type {
392425 case dateHistType :
393- aggBuilder = addDateHistogramAgg (aggBuilder , bucketAgg , from , to , defaultTimeField )
426+ var err error
427+ aggBuilder , err = addDateHistogramAgg (aggBuilder , bucketAgg , from , to , defaultTimeField )
428+ if err != nil {
429+ return err
430+ }
394431 case histogramType :
395432 aggBuilder = addHistogramAgg (aggBuilder , bucketAgg )
396433 case filtersType :
@@ -471,6 +508,8 @@ func processTimeSeriesQuery(q *Query, b *es.SearchRequestBuilder, from, to int64
471508 })
472509 }
473510 }
511+
512+ return nil
474513}
475514
476515func stringToIntWithDefaultValue (valueStr string , defaultValue int ) int {
0 commit comments