SigNoz/signoz · error

invalid having operator: %s

Error message

invalid having operator: %s

What it means

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.

Source

Thrown at pkg/query-service/model/v3/v3.go:1306

	HavingOperatorIn              HavingOperator = "IN"
	HavingOperatorNotIn           HavingOperator = "NOT_IN"
)

func (h HavingOperator) Validate() error {
	switch h {
	case HavingOperatorEqual,
		HavingOperatorNotEqual,
		HavingOperatorGreaterThan,
		HavingOperatorGreaterThanOrEq,
		HavingOperatorLessThan,
		HavingOperatorLessThanOrEq,
		HavingOperatorIn,
		HavingOperatorNotIn,
		HavingOperator(strings.ToLower(string(HavingOperatorIn))),
		HavingOperator(strings.ToLower(string(HavingOperatorNotIn))):
		return nil
	default:
		return fmt.Errorf("invalid having operator: %s", h)
	}
}

type Having struct {
	ColumnName string         `json:"columnName"`
	Operator   HavingOperator `json:"op"`
	Value      interface{}    `json:"value"`
}

func (h *Having) CacheKey() string {
	return fmt.Sprintf("column:%s,op:%s,value:%v", h.ColumnName, h.Operator, h.Value)
}

type QueryRangeResponse struct {
	ContextTimeout        bool      `json:"contextTimeout,omitempty"`
	ContextTimeoutMessage string    `json:"contextTimeoutMessage,omitempty"`
	ResultType            string    `json:"resultType"`
	Result                []*Result `json:"result"`

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Use one of the supported HavingOperator values, uppercase IN / NOT-IN (lowercase accepted)
  2. Check pkg/query-service/model/v3 for the operator list supported by your backend version and upgrade if a newer operator is needed

Example fix

// before
{"op":"contains","columnName":"value","value":[100]}
// after
{"op":">","columnName":"value","value":[100]}
Defensive patterns

Strategy: validation

Validate before calling

var validOps = map[string]bool{"=":true,"!=":true,">":true,">=":true,"<":true,"<=":true,"IN":true,"NOT-IN":true,"in":true,"not-in":true}
if !validOps[string(h.Op)] { return fmt.Errorf("unsupported having op %q", h.Op) }

Type guard

func isValidHavingOp(op v3.HavingOperator) bool { return op.Validate() == nil }

Prevention

When it happens

Trigger: A Having block with "op":"in" spelled as "In", or an unsupported operator like "=~" or "contains".

Common situations: Copy-pasting WHERE-clause syntax into HAVING; version differences where newer operators aren't in the deployed backend's switch statement.

Related errors


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