#7739·chroma

[Bug]: SparseVector accepts non-finite values and non-string labels that fail at the transport boundary

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

What happened?

SparseVector.__post_init__ validates that values are numbers and that labels is a list of matching length, but it does not check that float values are finite or that each label is a string.

Two inputs are accepted that cannot be represented downstream:

  1. Non-finite float values:
python
from chromadb.base_types import SparseVector

sv = SparseVector(indices=[0], values=[float("nan")])
sv.to_dict()
# {'#type': 'sparse_vector', 'indices': [0], 'values': [nan]}

The dict is serialized to JSON as {"values": [null]}, which fails f32 decoding server-side. If a null value is ever returned to the client, SparseVector.from_dict raises ValueError on it as well:

python
SparseVector.from_dict({"#type": "sparse_vector", "indices": [0], "values": [None]})
# ValueError: SparseVector values must be numbers, got NoneType at position 0
  1. Non-string labels:
python
SparseVector(indices=[0], values=[1.0], labels=[123])
# accepted; to_dict() emits {"tokens": [123]}, which fails string[] decoding

Expected behavior

Both cases should be rejected at construction with a clear ValueError, the same way non-numeric values and unsorted indices already are.

Versions

chromadb 1.5.9 (current main), Python 3.12.

Proposed fix

In SparseVector.__post_init__, reject non-finite float values (math.isfinite) and non-str labels. This is the same fail-fast treatment metadata floats need (see also the discussion around non-finite metadata values), applied to sparse vector values and labels.