weaviate/weaviate · error

process descending window: %w

Error message

process descending window: %w

What it means

In a descending sort on a roaring-set bucket, results are produced in windows of quantile keys. When processing one such window (processDESCWindow) fails, this error wraps and labels the failure as 'process descending window', preserving the underlying cause (bucket read error, nesting sub-sort failure, etc.).

Source

Thrown at adapters/repos/db/sorter/inverted_sorter.go:238

	startTime := time.Now()
	hasMoreNesting := len(sort) > 1
	qks := is.quantileKeysForDescSort(ctx, limit, ids, bucket, nesting)

	foundIDs := make([]uint64, 0, limit)
	seeksRequired := 0
	idCountBeforeCutoff := 0
	rowsEvaluated := 0
	whenComplete := is.annotateDESC(ctx, nesting, len(qks), startTime, &rowsEvaluated, &idCountBeforeCutoff, &seeksRequired)
	defer whenComplete()

	for qkIndex := len(qks) - 1; qkIndex >= 0; qkIndex-- {
		seeksRequired++
		startKey, endKey := cursorKeysForDESCWindow(qks, qkIndex)

		idsInWindow, rowsInWindow, err := is.processDESCWindow(ctx, bucket,
			startKey, endKey, ids, limit, nesting, hasMoreNesting, sort)
		if err != nil {
			return nil, fmt.Errorf("process descending window: %w", err)
		}

		rowsEvaluated += rowsInWindow

		// prepend ids from window, the full list will be reversed at the end
		foundIDs = append(idsInWindow, foundIDs...)
		if len(foundIDs) >= limit {
			// we have enough ids, no need to continue
			break
		}
	}

	// the inverted index is in ASC order meaning our best matches are at the
	// very end of the slice, we need to reverse it before applying the cut-off
	slices.Reverse(foundIDs)
	idCountBeforeCutoff = len(foundIDs)
	if len(foundIDs) > limit {
		foundIDs = foundIDs[:limit]

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Read the wrapped (%w) inner error to find the actual cause — I/O, closed bucket, or nested-sort failure.
  2. Retry the query if a transient shutdown/offload race closed the bucket.
  3. Check disk health and LSM segment integrity for the affected shard if errors repeat.
  4. Reduce sort nesting depth or simplify the query (fewer sort criteria) if nested sorts are implicated.

Example fix

// before
return nil, fmt.Errorf("process descending window: %w", err)
// after — caller distinguishes transient vs persistent
if errors.Is(err, lsmkv.ErrBucketNotFound) {
	return nil, err // non-retryable, property bucket missing
}
return nil, fmt.Errorf("process descending window: %w", err) // retryable path
Defensive patterns

Strategy: retry

Validate before calling

if bucket == nil || bucket.Strategy() != lsmkv.StrategyRoaringSet { return errors.New("desc sort requires open roaring-set bucket") }

Try / catch

ids, err := sorter.SortDocIDs(ctx, limit, sort, ids)
if err != nil && errors.Is(err, errDescWindow) && isTransient(err) {
	ids, err = sorter.SortDocIDs(ctx, limit, sort, ids) // one retry
}

Prevention

When it happens

Trigger: sortRoaringSetDESC iterating quantile key windows when the underlying bucket cursor read fails, the bucket is closed mid-scan, or a nested sub-sort (startNestedSort) inside the window returns an error.

Common situations: Desc-order sort queries racing shard shutdown/offload; disk I/O errors during cursor scans; deep nesting of sorts causing a failure in an inner sortDocIDsWithNesting call; LSM corruption in the property's roaring-set bucket.

Related errors


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