Tencent/WeKnora · error

logical operator %s requires an array of conditions

Error message

logical operator %s requires an array of conditions

What it means

The public filter type's UnmarshalJSON parses AND/OR conditions expecting their Value to arrive as a JSON array of condition objects. It returns this error when the decoded Value is not []any — e.g. a scalar, object, or string was supplied for a logical operator.

Source

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

		Field    string `json:"field,omitempty"`
		Operator string `json:"operator"`
		Value    any    `json:"value,omitempty"`
	}

	var aux Alias
	if err := json.Unmarshal(data, &aux); err != nil {
		return err
	}

	c.Field = aux.Field
	c.Operator = strings.ToLower(aux.Operator)

	// Handle logical operators (and/or) - Value should be []*UniversalFilterCondition
	if c.Operator == operatorAnd || c.Operator == operatorOr {
		// Value can be an array of conditions
		valueSlice, ok := aux.Value.([]any)
		if !ok {
			return fmt.Errorf("logical operator %s requires an array of conditions", c.Operator)
		}

		conditions := make([]*universalFilterCondition, 0, len(valueSlice))
		for i, v := range valueSlice {
			condBytes, err := json.Marshal(v)
			if err != nil {
				return fmt.Errorf("failed to marshal condition at index %d: %w", i, err)
			}

			var cond universalFilterCondition
			if err := json.Unmarshal(condBytes, &cond); err != nil {
				return fmt.Errorf("failed to unmarshal condition at index %d: %w", i, err)
			}
			conditions = append(conditions, &cond)
		}
		c.Value = conditions
	} else {
		c.Value = aux.Value

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Wrap the sub-condition in a JSON array for AND/OR: "value": [{...}]
  2. Use an explicit AND/OR with one element if only one condition applies
  3. Validate filter JSON shape before unmarshaling

Example fix

// before
{"operator":"AND","value":{"field":"a","operator":"EQUAL","value":1}}
// after
{"operator":"AND","value":[{"field":"a","operator":"EQUAL","value":1}]}
Defensive patterns

Strategy: validation

Validate before calling

var raw map[string]any
if err := json.Unmarshal(data, &raw); err != nil { return err }
if op, _ := raw["operator"].(string); op == "AND" || op == "OR" {
  if _, ok := raw["value"].([]any); !ok {
    return fmt.Errorf("logical operator %s requires value array", op)
  }
}

Type guard

func logicalValueIsArray(raw map[string]any) bool {
  op, _ := raw["operator"].(string)
  if op != "AND" && op != "OR" { return true }
  _, ok := raw["value"].([]any)
  return ok
}

Try / catch

var f Filter
if err := json.Unmarshal(data, &f); err != nil {
  if strings.Contains(err.Error(), "requires an array of conditions") {
    return nil, fmt.Errorf("malformed logical node in filter JSON: %w", err)
  }
  return nil, err
}

Prevention

When it happens

Trigger: Unmarshaling JSON where "operator" is AND/OR but "value" is not an array (a single condition object, null, a string, or a number).

Common situations: Hand-written filter JSON wrapping a single condition without an array; an API client sending one sub-condition; schema changes where value became an object.

Related errors


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