{"record":{"id":"096b266892399b53","repo":"chroma-core/chroma","slug":"invalid-task-self-query-config-get-task","errorCode":null,"errorMessage":"Invalid task: {self.query_config.get('task')}","messagePattern":"Invalid task: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/utils/embedding_functions/huggingface_sparse_embedding_function.py","lineNumber":128,"sourceCode":"    def embed_query(self, input: Documents) -> SparseVectors:\n        try:\n            from sentence_transformers import SparseEncoder\n        except ImportError:\n            raise ValueError(\n                \"The sentence_transformers python package is not installed. Please install it with `pip install sentence_transformers`\"\n            )\n        model = cast(SparseEncoder, self._model)\n        if self.query_config is not None:\n            if self.query_config.get(\"task\") == \"document\":\n                embeddings = model.encode_document(\n                    list(input),\n                )\n            elif self.query_config.get(\"task\") == \"query\":\n                embeddings = model.encode_query(\n                    list(input),\n                )\n            else:\n                raise ValueError(f\"Invalid task: {self.query_config.get('task')}\")\n\n            sparse_vectors: SparseVectors = []\n\n            for vec in embeddings:\n                # Convert sparse tensor to dense array if needed\n                if hasattr(vec, \"to_dense\"):\n                    vec_dense = vec.to_dense().numpy()\n                else:\n                    vec_dense = vec.numpy() if hasattr(vec, \"numpy\") else np.array(vec)\n\n                nz = np.where(vec_dense != 0)[0]\n                sparse_vectors.append(\n                    normalize_sparse_vector(\n                        indices=nz.tolist(), values=vec_dense[nz].tolist()\n                    )\n                )\n\n            return sparse_vectors","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/utils/embedding_functions/huggingface_sparse_embedding_function.py#L110-L146","documentation":"In embed_query, when query_config is provided it is dispatched on query_config.get('task'): 'document' → encode_document, 'query' → encode_query. A query_config dict that is missing the 'task' key (get returns None) or carries an unrecognized value raises ValueError(f\"Invalid task: {query_config.get('task')}\"). The expected shape is the TypedDict HuggingFaceSparseEmbeddingFunctionQueryConfig = {'task': Literal['document','query']}.","triggerScenarios":"Passing query_config={} (empty dict) or query_config={'task': 'querys'}/{'task': None} to the constructor and then calling embed_query/collection.query; passing extra keys alongside a missing 'task'; reusing a Nomic-style query config whose task values are 'search_query' rather than 'query'.","commonSituations":"Building query_config dynamically (e.g. from user settings) where 'task' can be absent; migrating configs between Nomic (search_document/search_query vocabulary) and HuggingFace sparse ('document'/'query'); treating query_config as optional-metadata dict instead of a required-key TypedDict.","solutions":["Always include a valid 'task' key: query_config={'task': 'query'}","Pass query_config=None (the default) to make embed_query reuse the top-level task setting","Validate before constructing: assert set(('task',)) <= query_config.keys() and query_config['task'] in ('document', 'query')"],"exampleFix":"# before\nef = HuggingFaceSparseEmbeddingFunction(\n    model_name=\"prithivida/Splade_PP_en_v1\", device=\"cpu\", task=\"document\",\n    query_config={\"model\": \"x\"},  # no \"task\" key -> \"Invalid task: None\"\n)\n\n# after\nef = HuggingFaceSparseEmbeddingFunction(\n    model_name=\"prithivida/Splade_PP_en_v1\", device=\"cpu\", task=\"document\",\n    query_config={\"task\": \"query\"},\n)","handlingStrategy":"validation","validationCode":"def build_query_config(cfg: dict | None):\n    if cfg is None:\n        return None\n    task = cfg.get(\"task\")\n    if task not in (\"document\", \"query\"):\n        raise ValueError(\n            f\"query_config['task'] must be 'document' or 'query', got {task!r}\"\n        )\n    return {\"task\": task}\n\nef = HuggingFaceSparseEmbeddingFunction(\n    model_name=\"prithivida/Splade_PP_en_v1\",\n    device=\"cpu\",\n    task=\"document\",\n    query_config=build_query_config(user_cfg),\n)","typeGuard":"from typing import TypedDict, Literal\n\nclass QueryConfig(TypedDict):\n    task: Literal[\"document\", \"query\"]\n\ndef is_valid_query_config(c: object) -> bool:\n    return (\n        isinstance(c, dict)\n        and set(c) >= {\"task\"}\n        and c[\"task\"] in (\"document\", \"query\")\n    )","tryCatchPattern":"try:\n    ef.embed_query([\"q\"])\nexcept ValueError as e:\n    if str(e).startswith(\"Invalid task:\"):\n        raise ValueError(\"query_config must contain task='document'|'query'\") from e\n    raise","preventionTips":["Construct query_config only through a helper that guarantees the 'task' key","Type it with the HuggingFaceSparseEmbeddingFunctionQueryConfig TypedDict so mypy flags missing keys","Do not mix task vocabularies across EFs ('search_query' is Nomic, 'query' is HF sparse)"],"tags":["python","validation","enum","sparse-embeddings","query-config"],"backgroundTag":"invalid-parameter-value","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}