chroma-core/chroma · error · ValueError

Keyword argument {key} is not a primitive type

Error message

Keyword argument {key} is not a primitive type

What it means

The kwargs are validated to be JSON-friendly primitives (str, int, float, bool, list, dict, tuple) because they are persisted in the function's config and must round-trip through serialization. Any non-primitive value - None, model objects, callables, numpy scalars - is rejected by key name before SparseTextEmbedding is constructed. Note that None is not in the allowed set, so optional kwargs cannot be nulled out, only omitted.

Source

Thrown at chromadb/utils/embedding_functions/fastembed_sparse_embedding_function.py:66

        try:
            from fastembed import SparseTextEmbedding
        except ImportError:
            raise ValueError(
                "The fastembed python package is not installed. Please install it with `pip install fastembed`"
            )

        self.task = task
        self.query_config = query_config
        self.model_name = model_name
        self.cache_dir = cache_dir
        self.threads = threads
        self.cuda = cuda
        self.device_ids = device_ids
        self.lazy_load = lazy_load
        validate_embedding_function_kwargs_are_safe(kwargs)
        for key, value in kwargs.items():
            if not isinstance(value, (str, int, float, bool, list, dict, tuple)):
                raise ValueError(f"Keyword argument {key} is not a primitive type")
        self.kwargs = kwargs
        self._model = SparseTextEmbedding(
            model_name, cache_dir, threads, cuda, device_ids, lazy_load, **kwargs
        )

    def __call__(self, input: Documents) -> SparseVectors:
        """Generate embeddings for the given documents.

        Args:
            input: Documents to generate embeddings for.

        Returns:
            Embeddings for the documents.
        """
        try:
            from fastembed import SparseTextEmbedding
        except ImportError:
            raise ValueError(

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Omit optional kwargs entirely instead of passing None.
  2. Pass only serializable values; keep objects and callables out of anything that goes into EF config.
  3. Filter kwargs before construction: {k: v for k, v in kwargs.items() if v is not None}.

Example fix

# before
ef = FastembedSparseEmbeddingFunction(model_name='Qdrant/bm25', cache_dir=None, threads=None)
# ValueError: Keyword argument cache_dir is not a primitive type

# after
clean = {k: v for k, v in kwargs.items() if v is not None}
ef = FastembedSparseEmbeddingFunction(model_name='Qdrant/bm25', **clean)
Defensive patterns

Strategy: validation

Validate before calling

PRIMITIVES = (str, int, float, bool, list, dict, tuple)
clean = {k: v for k, v in kwargs.items()
         if v is not None and isinstance(v, PRIMITIVES)}

Type guard

PRIMITIVES = (str, int, float, bool, list, dict, tuple)

def kwargs_are_primitive(kwargs: dict) -> bool:
    return all(isinstance(v, PRIMITIVES) for v in kwargs.values())

Prevention

When it happens

Trigger: Passing kwargs like {'cache_dir': None}, {'threads': None}, a custom object, or a lambda to FastembedSparseEmbeddingFunction; the message names the offending key.

Common situations: Building kwargs programmatically from YAML/env config where absent values default to None; forwarding **options dicts that include callables; copy-pasting fastembed examples that pass objects.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/821b032d92268152. Report an issue: GitHub.