Tencent/WeKnora · error
unsupported comparison operator: %s
Error message
unsupported comparison operator: %s
What it means
convertComparisonCondition looks up cond.Operator in the comparisonOperators map and returns 'unsupported comparison operator: %s' when the operator has no Milvus expression translation. Only operators present in that map (e.g. ==, !=, >, <, in) are supported; anything else cannot be rendered into a Milvus boolean expression.
Source
Thrown at internal/application/repository/retriever/milvus/filter.go:86
type filter struct{}
func (c *filter) Convert(cond *universalFilterCondition) (*convertResult, error) {
var counter int
return c.convertCondition(cond, &counter)
}
func (c *filter) convertComparisonCondition(
cond *universalFilterCondition,
counter *int,
) (*convertResult, error) {
condField := cond.Field
if condField == "" || cond.Value == nil {
return nil, fmt.Errorf("milvus filter condition is nil")
}
operator, ok := comparisonOperators[cond.Operator]
if !ok {
return nil, fmt.Errorf("unsupported comparison operator: %s", cond.Operator)
}
paramName := c.convertParamName(cond.Field, counter)
return &convertResult{
exprStr: fmt.Sprintf("%s %s {%s}", condField, operator, paramName),
params: map[string]any{paramName: cond.Value},
}, nil
}
func (c *filter) convertLogicalCondition(
cond *universalFilterCondition,
counter *int,
) (*convertResult, error) {
if cond.Value == nil {
return nil, fmt.Errorf("milvus filter condition is nil")
}
conds, ok := cond.Value.([]*universalFilterCondition)
if !ok {View on GitHub (pinned to 988cbb0330)
Solutions
- Check the operator value in the error and replace it with one supported by comparisonOperators (==, !=, >, >=, <, <=, in, etc.).
- If the semantic operator is needed, add a mapping entry translating it to a Milvus-supported expression (e.g. use text_match or range expressions).
- Normalize operator casing/aliases at the filter-parse boundary before conversion.
- Validate the operator against a whitelist in the caller before building conditions.
Example fix
// before
newCond("title", "contains", title) // 'contains' unsupported
// after
newCond("title", "in", []string{"prefix..."}) // or extend comparisonOperators with a text_match mapping Defensive patterns
Strategy: validation
Validate before calling
var supportedOps = map[string]bool{"==":true,"!=":true,">":true,">=":true,"<":true,"<=":true,"in":true}
if !supportedOps[cond.Operator] { return fmt.Errorf("operator %q not supported for milvus", cond.Operator) } Prevention
- Normalize operator casing and aliases at the filter-parse boundary.
- Whitelist operators per backend when sharing a filter DSL across stores.
- Extend comparisonOperators deliberately when adding new operators, with tests.
- Reject unsupported operators at the API surface rather than deep in conversion.
When it happens
Trigger: Passing an operator like 'contains', 'like', '~=', 'startsWith', or a database-specific SQL operator that the map does not cover, often when translating a filter DSL written for another vector store (e.g. Pinecone/Postgres) directly to Milvus.
Common situations: Cross-store filter DSLs reused between retrievers; frontend sending free-text operators; new operator added to the universal filter type without extending comparisonOperators; case mismatch ('IN' vs 'in').
Related errors
- milvus filter condition is nil
- invalid logical condition value type
- unsupported operator: %v
- empty logical condition
- in operator value must be a slice with at least one value: %
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/4d93dc58b5289947.
Report an issue: GitHub.