chroma-core/chroma · error · ValueError
Invalid task: {task}
Error message
Invalid task: {task} What it means
When query_config is provided, embed_query ignores self.task and dispatches on query_config["task"], again accepting only "document" or "query". Any other value raises this ValueError — including None, which is what you get when the dict simply lacks the "task" key, since it is read with .get(). So passing an empty query_config={} fails with "Invalid task: None" rather than falling back to a default.
Source
Thrown at chromadb/utils/embedding_functions/bm25_embedding_function.py:151
try:
from fastembed.sparse.bm25 import Bm25
except ImportError:
raise ValueError(
"The fastembed python package is not installed. Please install it with `pip install fastembed`"
)
model = cast(Bm25, self._model)
if self.query_config is not None:
task = self.query_config.get("task")
if task == "document":
embeddings = model.embed(
list(input),
)
elif task == "query":
embeddings = model.query_embed(
list(input),
)
else:
raise ValueError(f"Invalid task: {task}")
sparse_vectors: SparseVectors = []
for vec in embeddings:
sparse_vectors.append(
normalize_sparse_vector(
indices=vec.indices.tolist(), values=vec.values.tolist()
)
)
return sparse_vectors
else:
return self.__call__(input)
@staticmethod
def name() -> str:
return "bm25"View on GitHub (pinned to aecdd12c8a)
Solutions
- Include a valid task: query_config={"task": "query"} (or "document").
- If you do not need per-query overrides, pass query_config=None — embed_query then reuses self.task.
- Validate query_config at construction: task must be present and one of the two literals.
Example fix
# before: ValueError "Invalid task: passage" (or "Invalid task: None" for missing key)
ef = Bm25EmbeddingFunction(task="query", query_config={"task": "passage"})
qv = ef.embed_query(["search term"])
# after
ef = Bm25EmbeddingFunction(task="query", query_config={"task": "query"})
qv = ef.embed_query(["search term"]) Defensive patterns
Strategy: validation
Validate before calling
VALID_TASKS = {"document", "query"}
def make_query_config(query_config: dict | None) -> dict | None:
if query_config is None:
return None
task = query_config.get("task")
if task not in VALID_TASKS:
raise ValueError(f"query_config['task'] must be one of {sorted(VALID_TASKS)}, got {task!r}")
return query_config
ef = Bm25EmbeddingFunction(task="query", query_config=make_query_config(raw_qcfg)) Type guard
def is_valid_query_config(qcfg: object) -> bool:
return (
qcfg is None
or (isinstance(qcfg, dict) and qcfg.get("task") in ("document", "query"))
) Try / catch
try:
qv = ef.embed_query(queries)
except ValueError as e:
if "Invalid task" in str(e):
ef.query_config = {**ef.query_config, "task": "query"} # repair or re-construct with a valid task
qv = ef.embed_query(queries)
else:
raise Prevention
- Remember query_config={} fails with 'Invalid task: None' — always include the 'task' key.
- Pass query_config=None when you want embed_query to reuse self.task.
- Translate 'passage' → 'document' when porting query configs from other retrieval stacks.
When it happens
Trigger: Bm25EmbeddingFunction(task="query", query_config={"task": "passage"}) then embed_query(...); or query_config={} / {"k": 1.5} without a "task" key — .get("task") returns None and the error reads "Invalid task: None".
Common situations: Porting sentence-transformers query configs that use "passage"; storing extra BM25 parameters (k, b) in query_config and forgetting the required task key; assuming query_config={} means "use self.task".
Related errors
- Invalid task: {self.task}
- The fastembed python package is not installed. Please instal
- Failed to register sparse embedding function: {e}
- Keyword argument {key} is not a primitive type
- Unequal lengths for fields: {error_str}
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/8dace0a15719c50a.
Report an issue: GitHub.