Tencent/WeKnora · error

failed to unmarshal condition at index %d: %w

Error message

failed to unmarshal condition at index %d: %w

What it means

After re-marshaling an AND/OR child element, UnmarshalJSON decodes it into universalFilterCondition. This error wraps json.Unmarshal failures with the element's index and underlying cause (%w) — typically a child object missing required shape or having wrong field types.

Source

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

	// 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
	}

	return nil
}

// MarshalJSON implements custom JSON marshaling for UniversalFilterCondition.
func (c *universalFilterCondition) MarshalJSON() ([]byte, error) {
	type Alias struct {
		Field    string `json:"field,omitempty"`
		Operator string `json:"operator"`
		Value    any    `json:"value,omitempty"`
	}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Read the wrapped error to identify the type mismatch at the given index
  2. Fix the JSON at that index so each child has proper field/operator/value types
  3. Validate nested filter JSON with a schema before unmarshaling

Example fix

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

Strategy: try-catch

Validate before calling

var raw struct {
  Operator string   `json:"operator"`
  Value    []any    `json:"value"`
}
if err := json.Unmarshal(data, &raw); err != nil { return err }
for i, v := range raw.Value {
  m, ok := v.(map[string]any)
  if !ok || m["field"] == nil || m["operator"] == nil {
    return fmt.Errorf("child %d missing field/operator", i)
  }
}

Type guard

func childShapeOK(v any) bool {
  m, ok := v.(map[string]any)
  return ok && m["field"] != nil && m["operator"] != nil && m["value"] != nil
}

Try / catch

var f Filter
if err := json.Unmarshal(data, &f); err != nil {
  if strings.Contains(err.Error(), "failed to unmarshal condition at index") {
    return nil, fmt.Errorf("invalid child condition in logical filter: %w", err)
  }
  return nil, err
}

Prevention

When it happens

Trigger: A sub-condition object whose "field"/"operator"/"value" keys have types incompatible with the target struct (e.g. "value" as an object where a scalar is expected, or operator as a number).

Common situations: Malformed nested filter JSON from clients; renamed JSON keys after a library upgrade; deeply nested AND/OR with a typo in one leaf condition.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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