#23049·llama_index

[Bug]: similarity() returns nan for zero-norm embeddings, corrupting top-k selection

Author: betacatslingCreated Sep 14, 2026Updated Sep 29, 2026

Bug Description

similarity() in llama_index/core/base/embeddings/base.py divides by the product of vector norms in the default cosine branch:

python
product = np.dot(embedding1, embedding2)
norm = np.linalg.norm(embedding1) * np.linalg.norm(embedding2)
return product / norm

When either embedding is a zero vector (e.g. some providers return zero embeddings for empty text), the norm product is 0 and the function silently returns nan (with a RuntimeWarning).

The nan leaks into top-k selection: get_top_k_embeddings() pushes (similarity, id) tuples onto a heap, and comparisons against nan are always false, so the nan-scored node survives pruning and is returned in top-k results over legitimately scored nodes.

Version

llama-index-core 0.14.24 (reproduced on main @ 7169bcd)

Steps to Reproduce

python
from llama_index.core.base.embeddings.base import similarity
from llama_index.core.indices.query.embedding_utils import get_top_k_embeddings

similarity([0.0, 0.0], [1.0, 0.0])   # nan, expected 0.0

sims, ids = get_top_k_embeddings(
    [1.0, 0.0], [[1.0, 0.0], [0.5, 0.5], [0.0, 0.0]], similarity_top_k=2
)
# sims == [1.0, nan], ids == [0, 2]
# the zero-vector node (id 2) is returned; the legitimately scored node (id 1, ~0.707) is dropped

Suggested Fix

Return 0.0 when the norm product is zero:

python
if norm == 0:
    return 0.0
return product / norm

This matches the zero-vector convention used by sklearn's cosine similarity.