Tencent/WeKnora · error

milvus filter condition is nil

Error message

milvus filter condition is nil

What it means

In the Milvus universal filter converter, convertComparisonCondition rejects any condition whose Field is empty or whose Value is nil, returning the sentinel error 'milvus filter condition is nil'. A comparison condition needs both a field name and a value to render into a Milvus boolean expression like "field == {param}". This is a caller-side filter construction bug.

Source

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

type convertResult struct {
	exprStr string
	params  map[string]any
}

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 {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Validate each condition before conversion: skip conditions with empty Field or nil Value instead of adding them.
  2. In filter-building helpers, dereference pointer fields only when non-nil.
  3. Sanitize incoming JSON filters to drop keys with null values before mapping to conditions.
  4. Return a clear validation error to the upstream caller identifying which field was empty.

Example fix

// before
conds = append(conds, newCond("category", categoryValue)) // categoryValue may be nil
// after
if categoryValue != nil && categoryField != "" {
	conds = append(conds, newCond(categoryField, categoryValue))
}
Defensive patterns

Strategy: validation

Validate before calling

func validComparison(c *universalFilterCondition) bool {
	return c != nil && c.Field != "" && c.Value != nil
}
conds := filterSlice(validComparison)

Type guard

func hasFieldAndValue(c *universalFilterCondition) bool {
	return c != nil && c.Field != "" && c.Value != nil
}

Prevention

When it happens

Trigger: Building a filter condition with Field left as "" or Value left as nil — e.g. optional fields omitted from a struct being added as conditions with nil values, or JSON filter input where a key exists but its value is null.

Common situations: Unmarshaled filter JSON with null values; conditional Go code that appends a condition before checking whether the variable is set; struct-tag driven filter builders that don't skip nil pointer fields.

Related errors


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