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 v3 traces query builder builds exists/not-exists predicates by comparing the column to ''. This is only valid for custom attributes or string-typed columns; applying exists/nexists to a numeric or other typed fixed column is rejected.

Source

Thrown at pkg/query-service/app/traces/v3/query_builder.go:210

		}
	}
	queryString := strings.Join(conditions, " AND ")

	if len(queryString) > 0 {
		queryString = " AND " + queryString
	}
	return queryString, nil
}

func ExistsSubQueryForFixedColumn(key v3.AttributeKey, op v3.FilterOperator) (string, error) {
	if key.DataType == v3.AttributeKeyDataTypeString {
		if op == v3.FilterOperatorExists {
			return fmt.Sprintf("%s %s ''", key.Key, tracesOperatorMappingV3[v3.FilterOperatorNotEqual]), nil
		} else {
			return fmt.Sprintf("%s %s ''", key.Key, 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 handleEmptyValuesInGroupBy(groupBy []v3.AttributeKey) (string, error) {
	filterItems := []v3.FilterItem{}
	if len(groupBy) != 0 {
		for _, item := range groupBy {
			if !item.IsColumn {
				filterItems = append(filterItems, v3.FilterItem{
					Key:      item,
					Operator: v3.FilterOperatorExists,
				})
			}
		}
	}
	if len(filterItems) != 0 {
		filterSet := v3.FilterSet{
			Operator: "AND",

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Remove the exists filter on the non-string fixed column
  2. If you need presence semantics on a numeric column, use a comparison like > 0 instead
  3. Apply exists only to custom attributes or string columns

Example fix

// before
{"key":"duration_ns","operator":"exists"}

// after
{"key":"duration_ns","operator":">","value":0}
Defensive patterns

Strategy: type-guard

Validate before calling

if isNonStringFixedColumn(item.Key) && (op == v3.FilterOperatorExists || op == v3.FilterOperatorNexists) {
    return fmt.Errorf("exists not allowed on %s", item.Key.Key)
}

Type guard

func existsAllowed(key v3.AttributeKey) bool {
    return key.Type == v3.AttributeKeyTypeTag || key.DataType == v3.AttributeKeyDataTypeString
}

Prevention

When it happens

Trigger: Using the exists or not-exists operator on a fixed traces column (e.g. duration_ns) whose type is not string and is not a custom attribute.

Common situations: Users try to filter 'spans that have a duration' via exists; dashboards built generically apply exists to all columns including numeric ones.

Related errors


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