SigNoz/signoz · error
unsupported operation, exists and not exists can only be app
Error message
unsupported operation, exists and not exists can only be applied on custom attributes or string type columns
What it means
existsSubQueryForFixedColumn in the v4 traces query builder: exists/not-exists on traces is implemented as comparing the column against the empty string, which is only meaningful for custom attributes or string-typed columns. Any other fixed column type is rejected.
Source
Thrown at pkg/query-service/app/traces/v4/query_builder.go:101
func getSelectLabels(groupBy []v3.AttributeKey) string {
var labels []string
for _, tag := range groupBy {
name := getColumnName(tag, true)
labels = append(labels, fmt.Sprintf(" %s as `%s`", name, tag.Key))
}
return strings.Join(labels, ",")
}
// TODO(nitya): use the _exists columns as well in the future similar to logs
func existsSubQueryForFixedColumn(key v3.AttributeKey, op v3.FilterOperator) (string, error) {
if key.DataType == v3.AttributeKeyDataTypeString {
if op == v3.FilterOperatorExists {
return fmt.Sprintf("%s %s ''", getColumnName(key, true), tracesOperatorMappingV3[v3.FilterOperatorNotEqual]), nil
} else {
return fmt.Sprintf("%s %s ''", getColumnName(key, true), tracesOperatorMappingV3[v3.FilterOperatorEqual]), nil
}
} else {
return "", fmt.Errorf("unsupported operation, exists and not exists can only be applied on custom attributes or string type columns")
}
}
func BuildTracesFilterQuery(fs *v3.FilterSet, skipAllowed bool) (string, error) {
var conditions []string
if fs != nil && len(fs.Items) != 0 {
for _, item := range fs.Items {
// skip if it's a resource attribute or Span search scope attribute
// adding skipAllowed because traceFunnels requires the resource one as well.
if skipAllowed && (item.Key.Type == v3.AttributeKeyTypeResource || item.Key.Type == v3.AttributeKeyTypeSpanSearchScope) {
continue
}
val := item.Value
// generate the key
columnName := getColumnName(item.Key, true)View on GitHub (pinned to 5069bf80b0)
Solutions
- Drop the exists/nexists filter on the non-string fixed column
- Use an explicit comparison (e.g. > 0) for numeric columns
- Apply exists only to string columns or custom attributes
Example fix
// before
{"key":"duration_ns","operator":"nexists"}
// after
{"key":"http.route","operator":"nexists"} // string/custom attribute Defensive patterns
Strategy: type-guard
Validate before calling
if (op == v3.FilterOperatorExists || op == v3.FilterOperatorNexists) && !existsAllowedV4(key) {
return fmt.Errorf("exists not supported on %s", key.Key)
} Type guard
func existsAllowedV4(key v3.AttributeKey) bool {
return key.Type == v3.AttributeKeyTypeTag || key.DataType == v3.AttributeKeyDataTypeString
} Prevention
- Gate exists filters on column type in the frontend
- Document supported exists targets for trace queries
When it happens
Trigger: Using exists or not exists on a fixed traces column of non-string type (numeric, bool) in a query routed through the v4 traces builder.
Common situations: Generic dashboard filter builders applying exists to every column; saved views created before this restriction was enforced.
Related errors
- unsupported operation, exists and not exists can only be app
- unsupported operator %s
- invalid scope item type: %s
- multiple orderBy criteria are not supported for trace querie
- select columns cannot be empty for panelType %s
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/1d11e75fc07c7238.
Report an issue: GitHub.