Tencent/WeKnora · error

unsupported operator: %v

Error message

unsupported operator: %v

What it means

convertCondition switches on cond.Operator and returns this error in the default branch when the operator is not one of the supported comparison, logical, IN, NOT IN, or BETWEEN operators. The unrecognized operator is interpolated into the message.

Source

Thrown at internal/application/repository/retriever/milvus/filter.go:156

	cond *universalFilterCondition,
	counter *int,
) (*convertResult, error) {
	if cond == nil {
		return nil, fmt.Errorf("milvus filter condition is nil")
	}
	switch cond.Operator {
	case operatorEqual, operatorNotEqual, operatorGreaterThan,
		operatorGreaterThanOrEqual, operatorLessThan,
		operatorLessThanOrEqual, operatorLike, operatorNotLike:
		return c.convertComparisonCondition(cond, counter)
	case operatorAnd, operatorOr:
		return c.convertLogicalCondition(cond, counter)
	case operatorIn, operatorNotIn:
		return c.convertInCondition(cond, counter)
	case operatorBetween:
		return c.convertBetweenCondition(cond, counter)
	default:
		return nil, fmt.Errorf("unsupported operator: %v", cond.Operator)
	}
}

func (c *filter) convertInCondition(
	cond *universalFilterCondition,
	counter *int,
) (*convertResult, error) {
	condField := cond.Field
	if condField == "" || cond.Value == nil {
		return nil, fmt.Errorf("milvus filter condition is nil")
	}

	s := reflect.ValueOf(cond.Value)
	if s.Kind() != reflect.Slice || s.Len() <= 0 {
		return nil, fmt.Errorf("in operator value must be a slice with at least one value: %v", cond.Value)
	}

	paramName := c.convertParamName(cond.Field, counter)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Use only operators defined by this package (EQUAL, NOT_EQUAL, GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, LIKE, NOT_LIKE, AND, OR, IN, NOT_IN, BETWEEN)
  2. Check the exact operator string for typos or casing differences
  3. Map foreign operators to supported ones before calling Convert

Example fix

// before
cond := &UniversalFilterCondition{Field: "status", Operator: "eq", Value: "active"}
// after
cond := &UniversalFilterCondition{Field: "status", Operator: "EQUAL", Value: "active"}
Defensive patterns

Strategy: validation

Validate before calling

var supported = map[string]bool{
  "EQUAL": true, "NOT_EQUAL": true, "GREATER_THAN": true, "GREATER_THAN_OR_EQUAL": true,
  "LESS_THAN": true, "LESS_THAN_OR_EQUAL": true, "LIKE": true, "NOT_LIKE": true,
  "AND": true, "OR": true, "IN": true, "NOT_IN": true, "BETWEEN": true,
}
if !supported[cond.Operator] {
  return fmt.Errorf("operator %q not supported", cond.Operator)
}

Try / catch

res, err := f.Convert(ctx, cond)
if err != nil {
  var unsupported bool = strings.Contains(err.Error(), "unsupported operator")
  if unsupported { return nil, fmt.Errorf("bad operator in filter: %w", err) }
  return nil, err
}

Prevention

When it happens

Trigger: Setting Operator on a condition to a typo, an operator from another retriever backend, an empty string, or a Milvus-only operator not mapped in this package.

Common situations: Migrating filters between vector-store backends with different operator vocabularies; hand-writing JSON filters with lowercase or invented operator names; renames across library versions.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/00cb2b915cede600. Report an issue: GitHub.