weaviate/weaviate · error

malformed numerical aggregator state in shard result

Error message

malformed numerical aggregator state in shard result

What it means

Raised by mergeNumericalProp in the shard combiner when the source shard's grouped result contains a `_numericalAggregator` entry whose runtime type is not *numericalAggregator. The combiner merges raw distributions from each shard so mode/mean/median can be recomputed over the union; a wrong-typed entry makes that impossible.

Source

Thrown at adapters/repos/db/aggregator/shard_combiner.go:357

		case "_dateAggregator":
			continue
		default:
			return fmt.Errorf("unknown aggregation %q in shard result", propType)
		}
	}
	return nil
}

func (sc *ShardCombiner) mergeNumericalProp(first, second map[string]interface{}) error {
	if len(second) == 0 {
		return nil
	}

	// merge the raw distributions first, so that mode/mean/median recompute over both shards
	if source, ok := second["_numericalAggregator"]; ok {
		sourceTyped, ok := source.(*numericalAggregator)
		if !ok {
			return errors.New("malformed numerical aggregator state in shard result")
		}
		if combined, ok := first["_numericalAggregator"]; ok {
			combinedTyped, ok := combined.(*numericalAggregator)
			if !ok {
				return errors.New("malformed numerical aggregator state in shard result")
			}
			combinedTyped.absorb(sourceTyped)
		} else {
			first["_numericalAggregator"] = source
		}
	}

	for propType, value := range second {
		switch propType {
		case "count", "sum":
			sourceVal, ok := value.(float64)
			if !ok {
				return fmt.Errorf("malformed %q entry in shard result", propType)

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Ensure all cluster nodes run a compatible Weaviate version and retry the aggregation
  2. Isolate the offending shard by aggregating shard-by-shard
  3. Restore/rebuild the corrupt shard from backup or re-index its data
  4. Fix test helpers so `_numericalAggregator` is always a *numericalAggregator (e.g. newNumericalAggregator(...))

Example fix

// before
combined["_numericalAggregator"] = struct{ count int }{count: 5}
// after
combined["_numericalAggregator"] = newNumericalAggregator()
Defensive patterns

Strategy: type-guard

Validate before calling

func hasTypedNumericalAggregator(group map[string]interface{}) bool {
	_, ok := group["_numericalAggregator"].(*numericalAggregator)
	return ok
}

Type guard

if agg, ok := group["_numericalAggregator"].(*numericalAggregator); ok {
	combined.absorb(agg)
} else {
	return fmt.Errorf("malformed numerical aggregator state in shard result")
}

Try / catch

if err := combine(results); err != nil {
	if strings.Contains(err.Error(), "malformed numerical aggregator state") {
		// retry per-shard or drop the offending shard's contribution
	}
}

Prevention

When it happens

Trigger: Group-by numerical aggregation across shards where `second["_numericalAggregator"]` exists but holds something other than *numericalAggregator (type assertion failure on the source map value).

Common situations: Mixed-version clusters with changed internal aggregation types; corrupted or hand-crafted shard group maps; unit tests (testNumbers) that populate group maps with the wrong concrete type.

Understand the failure class

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/ea94cb063b22e77b. Report an issue: GitHub.