Skip to content

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

Description

@betacatsling

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:
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:

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:
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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions