weaviate/weaviate · error
get neighbor vec
Error message
get neighbor vec
What it means
Wrapped failure in reassignNeighbor when fetching the vector of a neighbor node fails with an error that is not a recoverable storobj.ErrNotFound. The cleanup worker needs the neighbor's vector to reconnect it after its tombstoned neighbor is removed; if the vector cannot be read for any reason other than 'object was deleted', the error is wrapped as 'get neighbor vec' and aborts the reassignment so the node stays in maintenance state.
Source
Thrown at adapters/repos/db/vector/hnsw/delete.go:656
}
neighborNode.Unlock()
var neighborVec []float32
var compressorDistancer compressionhelpers.CompressorDistancer
if h.compressed.Load() {
compressorDistancer, err = h.compressor.NewDistancerFromID(neighbor)
} else {
neighborVec, err = h.cache.Get(context.Background(), neighbor)
}
if err != nil {
var e storobj.ErrNotFound
if errors.As(err, &e) {
h.handleDeletedNode(e.DocID, "reassignNeighbor")
return true, nil
} else {
// not a typed error, we can recover from, return with err
return false, errors.Wrap(err, "get neighbor vec")
}
}
// the new recursive implementation no longer needs an entrypoint, so we can
// just pass this dummy value to make the neighborFinderConnector happy
neighborNode.markAsMaintenance()
defer neighborNode.unmarkAsMaintenance()
dummyEntrypoint := uint64(0)
if err := h.reconnectNeighboursOf(ctx, neighborNode, dummyEntrypoint, neighborVec, compressorDistancer,
neighborLevel, currentMaximumLayer, deleteList, processedIDs); err != nil {
return false, errors.Wrap(err, "find and connect neighbors")
}
h.metrics.CleanedUp()
return true, nil
}
View on GitHub (pinned to 75aa4b6d11)
Solutions
- Unwrap the error to see the underlying store failure and address it (disk, segment corruption, closed store)
- Retry cleanup — tombstoned nodes are re-attempted on later cleanup passes
- Check shard/segment integrity; restore from backup if segments are corrupted
- Ensure the shard is not being dropped or the store closed concurrently with cleanup
- If vectors are persistently unreadable for specific IDs, delete and re-insert those objects
Defensive patterns
Strategy: type-guard
Validate before calling
// Verify neighbor object exists and is readable before reassignment
vec, err := h.store.GetObject(ctx, neighborID)
if err != nil { return fmt.Errorf("neighbor %d unreadable: %w", neighborID, err) } Type guard
var e storobj.ErrNotFound
if errors.As(err, &e) {
h.handleDeletedNode(e.DocID, "reassignNeighbor")
return true, nil // recoverable
} Try / catch
vec, err := h.vectorByIndexNode(ctx, node)
if err != nil {
var e storobj.ErrNotFound
if errors.As(err, &e) { h.handleDeletedNode(e.DocID, "reassignNeighbor"); return true, nil }
return false, fmt.Errorf("get neighbor vec: %w", err)
} Prevention
- Treat storobj.ErrNotFound as success (node already deleted) — use errors.As, not string matching
- Monitor store I/O errors; run filesystem checks on the shard's storage volume
- Never drop a shard or close its store while cleanup goroutines are active
- Restore corrupted segments from backup instead of letting cleanup retry indefinitely
When it happens
Trigger: During tombstone cleanup, reassignNeighbor reads the neighbor's vector via the store; the read returns a non-ErrNotFound error (I/O failure, store closed/corrupted segment, deserialization failure). ErrNotFound is handled separately (the neighbor is treated as deleted).
Common situations: Disk I/O errors or corrupted LSM segments on the shard; a race where the shard is being dropped/closed while cleanup runs; store-level failures after an unclean shutdown.
Related errors
- delete entrypoint
- find and connect neighbors
- index is not hnsw
- drop vector index %q: %w
- delete from vector index of vector %q: %w
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/1c9174456a5a398d.
Report an issue: GitHub.