Tencent/WeKnora · error
in operator value must be a slice with at least one value: %
Error message
in operator value must be a slice with at least one value: %v
What it means
convertInCondition requires the IN/NOT_IN Value to be a slice containing at least one element. It uses reflection to check Value's kind and length and returns this error when Value is not a slice or is an empty slice, including Value's content in the message.
Source
Thrown at internal/application/repository/retriever/milvus/filter.go:171
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)
return &convertResult{
exprStr: fmt.Sprintf("%s %s {%s}", condField, strings.ToLower(cond.Operator), paramName),
params: map[string]any{paramName: cond.Value},
}, nil
}
func (c *filter) convertBetweenCondition(
cond *universalFilterCondition,
counter *int,
) (*convertResult, error) {
condField := cond.Field
if condField == "" || cond.Value == nil {
return nil, fmt.Errorf("milvus filter condition is nil")
}
View on GitHub (pinned to 988cbb0330)
Solutions
- Ensure Value is a non-empty slice (e.g. []string{...} or []int{...})
- If a single value is intended, use the EQUAL operator instead of IN
- Guard the length before building the condition
Example fix
// before
cond := &UniversalFilterCondition{Field: "tag", Operator: "IN", Value: "red"}
// after
cond := &UniversalFilterCondition{Field: "tag", Operator: "IN", Value: []string{"red"}} Defensive patterns
Strategy: validation
Validate before calling
rv := reflect.ValueOf(cond.Value)
if rv.Kind() != reflect.Slice || rv.Len() == 0 {
return fmt.Errorf("IN requires a non-empty slice")
} Type guard
func isInSlice(c *UniversalFilterCondition) bool {
if c.Value == nil { return false }
v := reflect.ValueOf(c.Value)
return v.Kind() == reflect.Slice && v.Len() > 0
} Try / catch
res, err := f.Convert(ctx, cond)
if err != nil {
if strings.Contains(err.Error(), "must be a slice") {
return nil, fmt.Errorf("IN value must be a non-empty slice: %w", err)
}
return nil, err
} Prevention
- Wrap single values in a one-element slice for IN
- Check slice length before constructing the condition
- Prefer typed builders ([]string, []int) over interface{} literals
When it happens
Trigger: IN condition with Value as a scalar (e.g. a single string), a map, or an empty slice like []string{}.
Common situations: Passing a single value intending 'equals'; JSON arrays that ended up empty after filtering; Go interface{} wrapping that loses the slice type.
Related errors
- between operator value must be a slice with two elements: %v
- milvus filter condition is nil
- unsupported comparison operator: %s
- invalid logical condition value type
- empty logical condition
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/5077d99815d615cb.
Report an issue: GitHub.