{"record":{"id":"1d11e75fc07c7238","repo":"SigNoz/signoz","slug":"unsupported-operation-exists-and-not-exists-can-o-1d11e7","errorCode":null,"errorMessage":"unsupported operation, exists and not exists can only be applied on custom attributes or string type columns","messagePattern":"unsupported operation, exists and not exists can only be applied on custom attributes or string type columns","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/query-service/app/traces/v4/query_builder.go","lineNumber":101,"sourceCode":"func getSelectLabels(groupBy []v3.AttributeKey) string {\n\tvar labels []string\n\tfor _, tag := range groupBy {\n\t\tname := getColumnName(tag, true)\n\t\tlabels = append(labels, fmt.Sprintf(\" %s as `%s`\", name, tag.Key))\n\t}\n\treturn strings.Join(labels, \",\")\n}\n\n// TODO(nitya): use the _exists columns as well in the future similar to logs\nfunc existsSubQueryForFixedColumn(key v3.AttributeKey, op v3.FilterOperator) (string, error) {\n\tif key.DataType == v3.AttributeKeyDataTypeString {\n\t\tif op == v3.FilterOperatorExists {\n\t\t\treturn fmt.Sprintf(\"%s %s ''\", getColumnName(key, true), tracesOperatorMappingV3[v3.FilterOperatorNotEqual]), nil\n\t\t} else {\n\t\t\treturn fmt.Sprintf(\"%s %s ''\", getColumnName(key, true), tracesOperatorMappingV3[v3.FilterOperatorEqual]), nil\n\t\t}\n\t} else {\n\t\treturn \"\", fmt.Errorf(\"unsupported operation, exists and not exists can only be applied on custom attributes or string type columns\")\n\t}\n}\n\nfunc BuildTracesFilterQuery(fs *v3.FilterSet, skipAllowed bool) (string, error) {\n\tvar conditions []string\n\n\tif fs != nil && len(fs.Items) != 0 {\n\t\tfor _, item := range fs.Items {\n\n\t\t\t// skip if it's a resource attribute or Span search scope attribute\n\t\t\t// adding skipAllowed because traceFunnels requires the resource one as well.\n\t\t\tif skipAllowed && (item.Key.Type == v3.AttributeKeyTypeResource || item.Key.Type == v3.AttributeKeyTypeSpanSearchScope) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tval := item.Value\n\t\t\t// generate the key\n\t\t\tcolumnName := getColumnName(item.Key, true)","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/query-service/app/traces/v4/query_builder.go#L83-L119","documentation":"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.","triggerScenarios":"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.","commonSituations":"Generic dashboard filter builders applying exists to every column; saved views created before this restriction was enforced.","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"],"exampleFix":"// before\n{\"key\":\"duration_ns\",\"operator\":\"nexists\"}\n\n// after\n{\"key\":\"http.route\",\"operator\":\"nexists\"} // string/custom attribute","handlingStrategy":"type-guard","validationCode":"if (op == v3.FilterOperatorExists || op == v3.FilterOperatorNexists) && !existsAllowedV4(key) {\n    return fmt.Errorf(\"exists not supported on %s\", key.Key)\n}","typeGuard":"func existsAllowedV4(key v3.AttributeKey) bool {\n    return key.Type == v3.AttributeKeyTypeTag || key.DataType == v3.AttributeKeyDataTypeString\n}","tryCatchPattern":null,"preventionTips":["Gate exists filters on column type in the frontend","Document supported exists targets for trace queries"],"tags":["signoz","traces","exists","v4","validation"],"backgroundTag":"unsupported-filter-operator","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}