SigNoz/signoz · error

unsupported aggregate operator

Error message

unsupported aggregate operator

What it means

The switch over AggregateOperator in buildMetricQueryForTable fell through to default, meaning the operator is not one of the known v3 table-view aggregators (sum, avg, max, min, count, count_distinct, *_rate, etc.). Unlike the rate/noop cases, this one means the operator value itself is unrecognized — often a typo, an empty value, or an operator added in a newer/older version than the running query-service.

Source

Thrown at pkg/query-service/app/metrics/v3/cumulative_table.go:184

		query = fmt.Sprintf(`SELECT %s toStartOfHour(now()) as ts, histogramQuantile(arrayMap(x -> toFloat64(x), groupArray(le)), groupArray(value), %.3f) as value FROM (%s) GROUP BY %s ORDER BY %s ts`, groupTagsWithoutLe, value, query, groupByWithoutLe, orderWithoutLe)
		return query, nil
	case v3.AggregateOperatorAvg, v3.AggregateOperatorSum, v3.AggregateOperatorMin, v3.AggregateOperatorMax:
		op := fmt.Sprintf("%s(value)", aggregateOperatorToSQLFunc[mq.AggregateOperator])
		query := fmt.Sprintf(queryTmpl, groupTags, op, filterSubQuery, groupBy, orderBy)
		return query, nil
	case v3.AggregateOperatorCount:
		op := "toFloat64(count(*))"
		query := fmt.Sprintf(queryTmpl, groupTags, op, filterSubQuery, groupBy, orderBy)
		return query, nil
	case v3.AggregateOperatorCountDistinct:
		op := "toFloat64(count(distinct(value)))"
		query := fmt.Sprintf(queryTmpl, groupTags, op, filterSubQuery, groupBy, orderBy)
		return query, nil
	case v3.AggregateOperatorNoOp:
		return "", fmt.Errorf("noop is not supported for table view")
	default:
		return "", fmt.Errorf("unsupported aggregate operator")
	}
}

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Set aggregateOperator to a value from the supported v3 enum (sum, avg, min, max, count, count_distinct, sum_rate, avg_rate, min_rate, max_rate)
  2. Align frontend/client and query-service versions so operator constants match
  3. Validate the operator client-side against the enum before calling the API

Example fix

// before
{"aggregateOperator":"rate_sum","queryType":"table"}
// after
{"aggregateOperator":"sum_rate","queryType":"table"}
Defensive patterns

Strategy: validation

Validate before calling

var validOps = map[string]bool{"sum":true,"avg":true,"min":true,"max":true,"count":true,"count_distinct":true,"rate":true,"sum_rate":true,"avg_rate":true,"min_rate":true,"max_rate":true,"noop":true}
if !validOps[aggregateOperator] {
  return fmt.Errorf("unknown aggregate operator %q", aggregateOperator)
}

Type guard

func isKnownAggregateOperator(op string) bool { _, ok := validOps[op]; return ok }

Try / catch

Catch 4xx from the query API, log the operator value, and fail fast with a config error rather than retrying.

Prevention

When it happens

Trigger: Passing aggregateOperator like "p95", "rate_sum", "" (empty), or any string not in the v3.AggregateOperator enum for a table query; also a client/server version skew where the client sends a newer operator constant the server doesn't know.

Common situations: API payloads hand-rolled without enum validation; older SigNoz query-service receiving queries from a newer frontend; typos in dashboard JSON; enum renamed between versions.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/e0f1d89420b67128. Report an issue: GitHub.