{"record":{"id":"85c28e75373dbfb7","repo":"SigNoz/signoz","slug":"invalid-having-operator-s","errorCode":null,"errorMessage":"invalid having operator: %s","messagePattern":"invalid having operator: (.+?)","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/query-service/model/v3/v3.go","lineNumber":1306,"sourceCode":"\tHavingOperatorIn              HavingOperator = \"IN\"\n\tHavingOperatorNotIn           HavingOperator = \"NOT_IN\"\n)\n\nfunc (h HavingOperator) Validate() error {\n\tswitch h {\n\tcase HavingOperatorEqual,\n\t\tHavingOperatorNotEqual,\n\t\tHavingOperatorGreaterThan,\n\t\tHavingOperatorGreaterThanOrEq,\n\t\tHavingOperatorLessThan,\n\t\tHavingOperatorLessThanOrEq,\n\t\tHavingOperatorIn,\n\t\tHavingOperatorNotIn,\n\t\tHavingOperator(strings.ToLower(string(HavingOperatorIn))),\n\t\tHavingOperator(strings.ToLower(string(HavingOperatorNotIn))):\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid having operator: %s\", h)\n\t}\n}\n\ntype Having struct {\n\tColumnName string         `json:\"columnName\"`\n\tOperator   HavingOperator `json:\"op\"`\n\tValue      interface{}    `json:\"value\"`\n}\n\nfunc (h *Having) CacheKey() string {\n\treturn fmt.Sprintf(\"column:%s,op:%s,value:%v\", h.ColumnName, h.Operator, h.Value)\n}\n\ntype QueryRangeResponse struct {\n\tContextTimeout        bool      `json:\"contextTimeout,omitempty\"`\n\tContextTimeoutMessage string    `json:\"contextTimeoutMessage,omitempty\"`\n\tResultType            string    `json:\"resultType\"`\n\tResult                []*Result `json:\"result\"`","sourceCodeStart":1288,"sourceCodeEnd":1324,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/query-service/model/v3/v3.go#L1288-L1324","documentation":"HavingOperator.Validate() accepts only the known operators (=, !=, >, >=, <, <=, IN, NOT-IN and their lowercase forms). Anything else hits the default branch and is reported verbatim in the message.","triggerScenarios":"A Having block with \"op\":\"in\" spelled as \"In\", or an unsupported operator like \"=~\" or \"contains\".","commonSituations":"Copy-pasting WHERE-clause syntax into HAVING; version differences where newer operators aren't in the deployed backend's switch statement.","solutions":["Use one of the supported HavingOperator values, uppercase IN / NOT-IN (lowercase accepted)","Check pkg/query-service/model/v3 for the operator list supported by your backend version and upgrade if a newer operator is needed"],"exampleFix":"// before\n{\"op\":\"contains\",\"columnName\":\"value\",\"value\":[100]}\n// after\n{\"op\":\">\",\"columnName\":\"value\",\"value\":[100]}","handlingStrategy":"validation","validationCode":"var validOps = map[string]bool{\"=\":true,\"!=\":true,\">\":true,\">=\":true,\"<\":true,\"<=\":true,\"IN\":true,\"NOT-IN\":true,\"in\":true,\"not-in\":true}\nif !validOps[string(h.Op)] { return fmt.Errorf(\"unsupported having op %q\", h.Op) }","typeGuard":"func isValidHavingOp(op v3.HavingOperator) bool { return op.Validate() == nil }","tryCatchPattern":null,"preventionTips":["Restrict having-operator dropdowns to the supported set","Don't reuse WHERE-clause operators in HAVING"],"tags":["signoz","query-builder","having","validation"],"backgroundTag":"query-validation-failed","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}