SigNoz/signoz · error
unsupported aggregate operator %s for panelType %s
Error message
unsupported aggregate operator %s for panelType %s
What it means
In buildTracesQuery's no-op branch, only PanelTypeTrace and PanelTypeList are handled; any other panel type (e.g. graph) combined with the no-op aggregate operator cannot be rendered as a trace query and is rejected.
Source
Thrown at pkg/query-service/app/traces/v4/query_builder.go:349
withSubQuery := fmt.Sprintf(withSubQueryWithLimits, constants.SIGNOZ_TRACE_DBNAME, constants.SIGNOZ_SPAN_INDEX_V3_LOCAL_TABLENAME, timeFilter, filterSubQuery)
afterSubQuery := tracesV3.AddLimitToQuery(constants.TraceExplorerSpanCountAfterSubQuery, mq.Limit)
if mq.Offset != 0 {
afterSubQuery = tracesV3.AddOffsetToQuery(afterSubQuery, mq.Offset)
}
query = fmt.Sprintf(constants.TraceExplorerSpanCountBeforeSubQuery, constants.SIGNOZ_TRACE_DBNAME, constants.SIGNOZ_SPAN_INDEX_V3) + withSubQuery + ") " + fmt.Sprintf(afterSubQuery, constants.SIGNOZ_TRACE_DBNAME, constants.SIGNOZ_SPAN_INDEX_V3, timeFilter)
}
// adding this to avoid the distributed product mode error which doesn't allow global in
query += " settings distributed_product_mode='allow', max_memory_usage=10000000000"
} else if panelType == v3.PanelTypeList {
if len(mq.SelectColumns) == 0 {
return "", fmt.Errorf("select columns cannot be empty for panelType %s", panelType)
}
selectLabels = getSelectLabels(mq.SelectColumns)
// add it to the select labels
queryNoOpTmpl := fmt.Sprintf("SELECT timestamp as timestamp_datetime, span_id as spanID, trace_id as traceID,%s ", selectLabels) + "from " + constants.SIGNOZ_TRACE_DBNAME + "." + constants.SIGNOZ_SPAN_INDEX_V3 + " where %s %s" + "%s"
query = fmt.Sprintf(queryNoOpTmpl, timeFilter, filterSubQuery, orderBy)
} else {
return "", fmt.Errorf("unsupported aggregate operator %s for panelType %s", mq.AggregateOperator, panelType)
}
return query, nil
// ---- NOOP ends here ----
}
having := tracesV3.Having(mq.Having)
if having != "" {
having = " having " + having
}
groupBy := tracesV3.GroupByAttributeKeyTags(panelType, options.GraphLimitQtype, mq.GroupBy...)
if groupBy != "" {
groupBy = " group by " + groupBy
}
aggregationKey := ""
if mq.AggregateAttribute.Key != "" {
aggregationKey = getColumnName(mq.AggregateAttribute, true)View on GitHub (pinned to 5069bf80b0)
Solutions
- Use an aggregate operator (count, avg(rate) etc.) instead of no-op for non trace/list panel types
- Switch the panel type to trace or list if you really need raw no-op behavior
Example fix
// before mq.AggregateOperator = v3.AggregateOperatorNoOp panelType = v3.PanelTypeGraph // after mq.AggregateOperator = v3.AggregateOperatorCount panelType = v3.PanelTypeGraph
Defensive patterns
Strategy: validation
Validate before calling
if mq.AggregateOperator == v3.AggregateOperatorNoOp && panelType != v3.PanelTypeTrace && panelType != v3.PanelTypeList {
return fmt.Errorf("no-op requires trace/list panel, got %s", panelType)
} Type guard
func noopAllowed(panelType v3.PanelType) bool {
return panelType == v3.PanelTypeTrace || panelType == v3.PanelTypeList
} Prevention
- Recompute aggregate operator when the user switches panel type
- Block no-op selection for graph/value panels
When it happens
Trigger: Sending AggregateOperator=no-op with panelType=graph, table, or value on a traces data source query.
Common situations: Switching a panel type in the UI without changing the aggregate operator; API calls copying a list query's structure onto a graph panel.
Related errors
- unsupported aggregate operator %s
- unsupported operation, exists and not exists can only be app
- invalid value for key %s: %v
- unsupported operator %s
- invalid scope item type: %s
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/978ea4d6c6aaa771.
Report an issue: GitHub.