weaviate/weaviate · error

index %q: %w

Error message

index %q: %w

What it means

This wrapper is produced by DB.MultiGet (adapters/repos/db/crud.go:133) when multiObjectByID on one of the involved indices fails. MultiGet batches object lookups per index and then fans out; if any single index's batched lookup errors, the whole MultiGet fails wrapped with that index's ID. The inner error is preserved via %w for errors.Is/As inspection.

Source

Thrown at adapters/repos/db/crud.go:133

		// store original position to make assembly easier later
		q.OriginalPosition = i

		for _, index := range db.indices {
			if index.Config.ClassName != schema.ClassName(q.ClassName) {
				continue
			}

			queue := byIndex[index.ID()]
			queue = append(queue, q)
			byIndex[index.ID()] = queue
		}
	}

	out := make(search.Results, len(query))
	for indexID, queries := range byIndex {
		indexRes, err := db.indices[indexID].multiObjectByID(ctx, queries, tenant)
		if err != nil {
			return nil, fmt.Errorf("index %q: %w", indexID, err)
		}

		for i, obj := range indexRes {
			if obj == nil {
				continue
			}
			res := obj.SearchResult(additional, tenant)
			out[queries[i].OriginalPosition] = *res
		}
	}

	return out, nil
}

// ObjectByID checks every index of the particular kind for the ID
//
// @warning: this function is deprecated by Object()
func (db *DB) ObjectByID(ctx context.Context, id strfmt.UUID,

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Read the wrapped inner error to identify which shard/tenant/IO problem caused the failure and address that root cause.
  2. Split the MultiGet into per-class requests so one failing index doesn't abort lookups for healthy classes.
  3. For multi-tenant classes, ensure the tenant is supplied for every lookup in the batch.
  4. Check shard/LSM health on the node holding indexID if errors persist (logs, disk space, compaction status).

Example fix

// before
res, err := db.MultiGet(ctx, query, tenant)
if err != nil { return err } // whole batch lost
// after
for _, q := range perClassQueries {
  res, err := db.MultiGet(ctx, q, tenant)
  if err != nil { log.Warnf("class %s lookup failed, skipping: %v", q.Class, err); continue }
  out = append(out, res...)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// validate classes exist and tenant is set before batch get
for _, class := range classes {
  if !classExists(schema, class) { return fmt.Errorf("class %q missing before MultiGet", class) }
}
if isMultiTenant(schema, classes[0]) && tenant == "" { return errors.New("tenant required") }

Try / catch

res, err := db.MultiGet(ctx, query, tenant)
if err != nil {
  var idxErr *IndexResolutionError // or inspect wrapped cause
  if errors.As(err, &idxErr) {
    log.Warnf("index %v failed in MultiGet: %v", idxErr.IndexID, err)
    return partialResults, nil // degrade instead of failing whole batch
  }
  return err
}

Prevention

When it happens

Trigger: Calling MultiGet (e.g. batch GetObjects by id across classes) where one of the target indices' multiObjectByID fails — typically storage/LSM read errors, tenant-resolution failures for multi-tenant classes, or internal shard lookup problems.

Common situations: Batch import pipelines resolving references by id across several collections; reference-graph processing where one corrupted or unhealthy shard poisons the entire multi-class batch read; multi-tenant requests where the tenant filter is missing for one involved class.

Related errors


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