{"record":{"id":"dc4a66283e191cb9","repo":"weaviate/weaviate","slug":"pick-entrypoint-at-level-beginning","errorCode":null,"errorMessage":"pick entrypoint at level beginning","messagePattern":"pick entrypoint at level beginning","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"adapters/repos/db/vector/hnsw/neighbor_connections.go","lineNumber":261,"sourceCode":"\t\t\t}\n\t\t\textraIDs = append(extraIDs, id)\n\t\t\ttop--\n\t\t\ttotal++\n\t\t}\n\t\tfor _, id := range n.pendingBuf {\n\t\t\tvisited.Visit(id)\n\t\t\terr := n.processRecursively(id, results, visited, level, top)\n\t\t\tif err != nil {\n\t\t\t\tn.graph.pools.visitedLists.Return(visited)\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tn.graph.pools.visitedLists.Return(visited)\n\t\t// use dynamic max connections only during tombstone cleanup\n\t\tmaxConnections = n.maximumConnections(level)\n\t} else {\n\t\tif err := n.pickEntrypoint(); err != nil {\n\t\t\treturn errors.Wrap(err, \"pick entrypoint at level beginning\")\n\t\t}\n\t\teps := priorityqueue.NewMin[any](1)\n\t\teps.Insert(n.entryPointID, n.entryPointDist)\n\t\tvar err error\n\n\t\tresults, err = n.graph.searchLayerByVectorWithDistancer(ctx, n.nodeVec, eps, n.graph.efConstruction,\n\t\t\tlevel, nil, n.distancer)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"search layer at level %d\", level)\n\t\t}\n\n\t\tn.graph.insertMetrics.findAndConnectSearch(before)\n\t\tbefore = time.Now()\n\t}\n\n\tif err := n.graph.selectNeighborsHeuristic(results, maxConnections-total, n.denyList); err != nil {\n\t\treturn errors.Wrap(err, \"heuristic\")\n\t}","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/repos/db/vector/hnsw/neighbor_connections.go#L243-L279","documentation":"At the start of doAtLevel, when there is no reusable entrypoint from cleanup state, the connector must pick an entrypoint node for the level's search (pickEntrypoint). Failure here means the connector could not establish a starting node and distance for searching this level — typically because the graph's entrypoint pointer is nil/inconsistent for the requested level.","triggerScenarios":"findAndConnectNeighbors at a level where the graph entrypoint is missing (e.g. targetLevel above the entrypoint's level with inconsistent state), or during reconnectNeighboursOf when the graph entrypoint has been removed by tombstone cleanup concurrently.","commonSituations":"Tombstone cleanup racing with inserts; an index whose entrypoint node was deleted (all objects deleted) then new inserts arrive; version-specific bugs in entrypoint promotion/demotion.","solutions":["Retry the insert — a concurrent entrypoint update usually resolves the transient inconsistency.","If all objects were deleted, expect the first re-insert to rebuild the entrypoint; ensure deletes/inserts are serialized per shard.","Upgrade to a version with fixed entrypoint handling if cleanup/insert races reproduce.","Reindex the collection if the entrypoint pointer stays inconsistent."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := bucket.Add(ctx, vector); err != nil {\n\tif strings.Contains(err.Error(), \"pick entrypoint at level beginning\") {\n\t\t// transient: entrypoint updated concurrently or graph was emptied\n\t\ttime.Sleep(50 * time.Millisecond)\n\t\treturn retry(ctx, vector)\n\t}\n\treturn err\n}","preventionTips":["Avoid deleting every object in a collection while inserts are in flight.","Keep cleanup and insert workloads from racing on the same shard.","Upgrade if entrypoint-promotion races are a known issue in your version."],"tags":["hnsw","vector-index","entrypoint","go"],"backgroundTag":"hnsw-entrypoint-missing","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}