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
Like other configurable embedding functions, Bm25EmbeddingFunction stores its **kwargs verbatim in get_config() so the function can be serialized and rebuilt later. To keep that persistence JSON-safe, the constructor rejects any kwarg value that is not a primitive (str, int, float, bool, list, dict, tuple) with this ValueError naming the offending key. fastembed model options must therefore be passed as plain data, not objects.
Source
Thrown at chromadb/utils/embedding_functions/bm25_embedding_function.py:73
from fastembed.sparse.bm25 import Bm25
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.cache_dir = cache_dir
self.k = k
self.b = b
self.avg_len = avg_len
self.language = language
self.token_max_length = token_max_length
self.disable_stemmer = disable_stemmer
self.specific_model_path = specific_model_path
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
bm25_kwargs = {
"model_name": "Qdrant/bm25",
}
optional_params = {
"cache_dir": cache_dir,
"k": k,
"b": b,
"avg_len": avg_len,
"language": language,
"token_max_length": token_max_length,
"disable_stemmer": disable_stemmer,
"specific_model_path": specific_model_path,
}
for key, value in optional_params.items():
if value is not None:
bm25_kwargs[key] = value
bm25_kwargs.update({k: v for k, v in kwargs.items() if v is not None})View on GitHub (pinned to aecdd12c8a)
Solutions
- Convert values to primitives before passing: str(path), int(x), float(y), plain dicts/lists.
- Use the dedicated typed parameters (cache_dir, k, b, language, ...) instead of pushing everything through **kwargs.
- Remove kwargs the Bm25 model does not actually accept.
Example fix
# before: ValueError "Keyword argument cache_path is not a primitive type"
ef = Bm25EmbeddingFunction(task="document", cache_path=Path("/tmp/cache"))
# after: use the typed parameter, or pass primitives
ef = Bm25EmbeddingFunction(task="document", cache_dir="/tmp/cache") Defensive patterns
Strategy: type-guard
Validate before calling
def is_primitive_kwarg(value: object) -> bool:
if isinstance(value, type):
return False
if isinstance(value, (str, int, float, bool)):
return True
if isinstance(value, (list, tuple)):
return all(is_primitive_kwarg(v) for v in value)
if isinstance(value, dict):
return all(isinstance(k, str) and is_primitive_kwarg(v) for k, v in value.items())
return False
bad = {k: v for k, v in bm25_kwargs.items() if not is_primitive_kwarg(v)}
if bad:
raise TypeError(f"Convert these kwargs to primitives: {list(bad)}")
ef = Bm25EmbeddingFunction(task="document", **bm25_kwargs) Type guard
def has_only_primitive_kwargs(kwargs: dict) -> bool:
return all(is_primitive_kwarg(v) for v in kwargs.values()) Try / catch
try:
ef = Bm25EmbeddingFunction(task="document", **kwargs)
except ValueError as e:
if "not a primitive type" in str(e):
kwargs = {k: (str(v) if isinstance(v, (os.PathLike,)) else v) for k, v in kwargs.items() if is_primitive_kwarg(v)}
ef = Bm25EmbeddingFunction(task="document", **kwargs)
else:
raise Prevention
- Use the typed constructor parameters (cache_dir, k, b, language, ...) instead of **kwargs where possible.
- Coerce Path and numpy types to str/int/float at your config boundary.
- Run a primitive-check over any config you intend to persist via get_config().
When it happens
Trigger: Bm25EmbeddingFunction(task="document", some_option=<object>) — e.g. passing a pathlib.Path, a numpy scalar, a config object, or a callable as one of the **kwargs forwarded to the Bm25 model.
Common situations: Passing Path objects for cache_dir-style options (cache_dir has its own typed parameter — objects only arrive via **kwargs); forwarding settings dicts from other frameworks that contain wrapped types; numpy bools/ints sneaking in from tuned parameters.
Related errors
- Keyword argument {key} is not a primitive type
- The fastembed python package is not installed. Please instal
- Invalid task: {self.task}
- Invalid task: {task}
- Invalid parameter name: {parameter.name}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/8ef2da50f88f2738.
Report an issue: GitHub.