chroma-core/chroma · error · ValueError
SparseVector values must be numbers, got {type(val).__name__
Error message
SparseVector values must be numbers, got {type(val).__name__} at position {i} What it means
SparseVector.__post_init__ requires every element of `values` to be an instance of Python `int` or `float`. Crucially, NumPy float scalars (np.float32, np.float64) are NOT subclasses of Python float, so numerically valid values pulled element-wise from a NumPy array still fail. None and strings fail as well. The message reports the offending type and position.
Source
Thrown at chromadb/base_types.py:73
if len(self.labels) != len(self.indices):
raise ValueError(
f"SparseVector labels must have the same length as indices and values, "
f"got {len(self.labels)} labels, {len(self.indices)} indices"
)
for i, idx in enumerate(self.indices):
if not isinstance(idx, int):
raise ValueError(
f"SparseVector indices must be integers, got {type(idx).__name__} at position {i}"
)
if idx < 0:
raise ValueError(
f"SparseVector indices must be non-negative, got {idx} at position {i}"
)
for i, val in enumerate(self.values):
if not isinstance(val, (int, float)):
raise ValueError(
f"SparseVector values must be numbers, got {type(val).__name__} at position {i}"
)
# Validate indices are sorted in strictly ascending order
if len(self.indices) > 1:
for i in range(1, len(self.indices)):
if self.indices[i] <= self.indices[i - 1]:
raise ValueError(
f"SparseVector indices must be sorted in strictly ascending order, "
f"found indices[{i}]={self.indices[i]} <= indices[{i-1}]={self.indices[i-1]}"
)
def to_dict(self) -> Dict[str, Any]:
"""Serialize to transport format with type tag.
Note: Uses 'tokens' as the wire format key name for compatibility
with the protobuf schema, even though the Python attribute is 'labels'.
"""View on GitHub (pinned to aecdd12c8a)
Solutions
- Convert before constructing: values = [float(v) for v in values] (float() accepts int, np.float32/64).
- Call .tolist() on the NumPy array holding the values to get native floats.
- Sanitize upstream: replace None/'' with 0.0 or drop the (index, value) pair before building the vector.
Example fix
// before vals = [tfidf_matrix[0, j] for j in cols] # np.float32 elements sv = SparseVector(indices=cols, values=vals) # ValueError: got float32 // after vals = [float(tfidf_matrix[0, j]) for j in cols] sv = SparseVector(indices=cols, values=vals)
Defensive patterns
Strategy: validation
Validate before calling
# Normalize values before constructing SparseVector values = [float(v) for v in values] # np.float32/np.float64/int -> float assert all(isinstance(v, (int, float)) for v in values) sv = SparseVector(indices=indices, values=values)
Type guard
def is_numeric_value_list(xs: object) -> bool:
"""Matches Chroma's check: isinstance(v, (int, float)) for every element."""
return isinstance(xs, list) and all(isinstance(v, (int, float)) for v in xs) Try / catch
try:
sv = SparseVector(indices=indices, values=values)
except ValueError as e:
raise ValueError(f'invalid sparse values for doc {doc_id}: {e}') from e Prevention
- Convert NumPy matrix rows with [float(x) for x in row] or .tolist(); never index arrays element-wise straight into Chroma.
- Reject or default None/'' weights upstream - decide the missing-value policy once.
- Test with the actual sklearn/torch outputs you will ship to production.
When it happens
Trigger: values taken element-wise from a NumPy array (arr[i] gives np.float32/np.float64); TfidfTransformer/sklearn outputs left as NumPy scalars; dicts parsed from JSON containing null or string numbers ('0.5') in the values slot.
Common situations: Sparse values from TF-IDF or BM25 pipelines that return NumPy matrices; values round-tripped through pandas; optional weights serialized as null/empty-string and passed through unmodified.
Related errors
- SparseVector indices must be integers, got {type(idx).__name
- Expected embeddings to be a list of floats or ints, a list o
- Sparse vector index must be created on a specific key. Pleas
- Deleting sparse vector index is not currently supported.
- limit must be a non-negative integer
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/c7afe769c0ead9ca.
Report an issue: GitHub.