{"record":{"id":"6a7c94622550a412","repo":"dgraph-io/dgraph","slug":"nil-vector-returned","errorCode":null,"errorMessage":"nil vector returned","messagePattern":"nil vector returned","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tok/hnsw/helper.go","lineNumber":50,"sourceCode":"\tVecKeyword           = \"__vector_\"\n\tvisitedVectorsLevel  = \"visited_vectors_level_\"\n\tdistanceComputations = \"vector_distance_computations\"\n\tsearchTime           = \"vector_search_time\"\n\tVecEntry             = \"__vector_entry\"\n\tVecDead              = \"__vector_dead\"\n\tVectorIndexMaxLevels = 5\n\tEfConstruction       = 16\n\tEfSearch             = 12\n\t// ByteData indicates the key stores data.\n\tByteData = byte(0x00)\n\t// DefaultPrefix is the prefix used for data, index and reverse keys so that relative\n\tDefaultPrefix = byte(0x00)\n\t// NsSeparator is the separator between the namespace and attribute.\n\tNsSeparator = \"-\"\n)\n\nvar (\n\terrNilVector           = errors.New(\"nil vector returned\")\n\terrFetchingPostingList = errors.New(\"error fetching posting list\")\n)\n\ntype SearchResult struct {\n\tnnUids        []uint64\n\ttraversalPath []uint64\n\textraMetrics  map[string]uint64\n}\n\nfunc (s *SearchResult) GetNnUids() []uint64 {\n\treturn s.nnUids\n}\n\nfunc (s *SearchResult) GetTraversalPath() []uint64 {\n\treturn s.traversalPath\n}\n\nfunc (s *SearchResult) GetExtraMetrics() map[string]uint64 {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/tok/hnsw/helper.go#L32-L68","documentation":"errNilVector is a sentinel error in the HNSW vector-index helper returned by getVecFromUid when the vector for a UID is nil, and by PickStartNode. It means the vector-index layer expected an embedding/pvector for a node but the stored value was absent or empty.","triggerScenarios":"Vector similarity search or traversal over an HNSW index where a posting/node lacks its vector payload — e.g. the embedding was never written, was deleted, or the predicate value is empty while the index entry remains.","commonSituations":"Partial writes where the index was built before the vector was persisted; manual deletes of the vector predicate without dropping/rebuilding the index; corrupted or truncated postings after restore/migration.","solutions":["Re-embed and re-write the vector for the affected UID(s), or delete the stale index entry","Drop and rebuild the vector index for the predicate (drop @index(hnsw(...)) then re-apply)","Check for interrupted writes/restore operations that left postings without vectors","Filter affected UIDs out of the search path and log them for backfill"],"exampleFix":"// before\nvec, err := getVecFromUid(ctx, uid) // errNilVector\n// after\nvec, err := getVecFromUid(ctx, uid)\nif errors.Is(err, errNilVector) {\n    backfillVector(uid) // recompute embedding, then retry\n    vec, err = getVecFromUid(ctx, uid)\n}","handlingStrategy":"fallback","validationCode":"// verify vector presence before relying on search results\nvec, err := getVecFromUid(ctx, uid)\nif err != nil || vec == nil {\n    markForBackfill(uid)\n    return nil\n}","typeGuard":null,"tryCatchPattern":"res, err := hnsw.SearchWithUid(ctx, idx, uid, opts)\nif err != nil {\n    if errors.Is(err, errNilVector) {\n        return backfillAndRetry(ctx, uid)\n    }\n    return err\n}","preventionTips":["Write vectors and index entries atomically; rebuild index after restores","Drop and recreate the HNSW index if vectors were manually deleted","Monitor for empty/nil embeddings at ingestion time","Backfill missing embeddings instead of letting index reads fail"],"tags":["dgraph","vector-index","hnsw","data-integrity"],"backgroundTag":"missing-embedding-vector","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}