Tencent/WeKnora · error
empty logical condition
Error message
empty logical condition
What it means
convertLogicalCondition builds a Milvus boolean expression from an AND/OR condition's children. It returns this error when, after iterating over the condition's children, no convertResult was produced (e.g. the children array was empty), so there is no expression string to emit.
Solutions
- Ensure AND/OR conditions contain at least one child condition in their Value array
- Validate the filter before calling Convert, rejecting logical operators with empty condition arrays
- Log the full condition tree to find the empty logical node
Example fix
// before
cond := &UniversalFilterCondition{Operator: "AND", Value: []*UniversalFilterCondition{}}
res, err := f.Convert(ctx, cond) // error: empty logical condition
// after
cond := &UniversalFilterCondition{Operator: "AND", Value: []*UniversalFilterCondition{
{Field: "age", Operator: "GREATER_THAN", Value: 18},
}}
res, err := f.Convert(ctx, cond) Defensive patterns
Strategy: validation
Validate before calling
func validLogical(c *UniversalFilterCondition) bool {
if c.Operator != "AND" && c.Operator != "OR" { return true }
conds, ok := c.Value.([]*UniversalFilterCondition)
return ok && len(conds) > 0
} Type guard
func isLogicalWithChildren(c *UniversalFilterCondition) bool {
conds, ok := c.Value.([]*UniversalFilterCondition)
return ok && len(conds) > 0
} Try / catch
res, err := f.Convert(ctx, cond)
if err != nil {
if strings.Contains(err.Error(), "empty logical condition") {
return nil, fmt.Errorf("filter has an AND/OR node with no sub-conditions: %w", err)
}
return nil, err
} Prevention
- Never construct AND/OR conditions with an empty Value slice
- Add a unit test covering empty logical nodes
- Centralize filter construction in a builder that enforces >=1 child
When it happens
Trigger: Calling Convert with a logical (AND/OR) condition whose Value array is empty, or whose children all fail silently to produce a result.
Common situations: Deserializing a filter from JSON where "value": [] for an AND/OR node; programmatically building nested filters and appending no sub-conditions.
Related errors
- milvus filter condition is nil
- between operator value must be a slice with two elements
- in operator value must be a slice with at least one value
- invalid logical condition value type
- unsupported comparison operator
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/ebfaa6fe4acda383.
Report an issue: GitHub.
Appendix: source
Thrown at internal/application/repository/retriever/milvus/filter.go:132
if childRes == nil || childRes.exprStr == "" {
continue
}
if condResult == nil {
condResult = childRes
continue
}
condResult.exprStr = fmt.Sprintf(
"(%s) %s (%s)",
condResult.exprStr,
strings.ToLower(cond.Operator),
childRes.exprStr,
)
maps.Copy(condResult.params, childRes.params)
}
if condResult == nil {
return nil, fmt.Errorf("empty logical condition")
}
return condResult, nil
}
func (c *filter) convertCondition(
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)View on GitHub (pinned to 988cbb0330)