{"record":{"id":"845d16ab070d9ac4","repo":"microsoft/semantic-kernel","slug":"hybrid-search-requires-keyword-field-name-in-opt","errorCode":null,"errorMessage":"Hybrid search requires 'keyword_field_name' in options.","messagePattern":"Hybrid search requires 'keyword_field_name' in options\\.","errorType":"exception","errorClass":"VectorStoreModelException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/azure_cosmos_db.py","lineNumber":838,"sourceCode":"                else f\"WHERE ({' AND '.join(rendered_clauses)}) \"\n            )\n        vector_field_name = vector_field.storage_name or vector_field.name\n        select_clause = self._build_select_clause(options.include_vectors)\n        params.append({\"name\": \"@vector\", \"value\": vector})\n        if vector_field.distance_function not in DISTANCE_FUNCTION_MAP_NOSQL:\n            raise VectorStoreModelException(\n                f\"Distance function '{vector_field.distance_function}' is not supported by Azure Cosmos DB NoSQL.\"\n            )\n        # Cosmos DB VectorDistance function only accepts 2 parameters: field and vector\n        # Distance function is configured in the vector index, not in the query\n        if search_type == SearchType.VECTOR:\n            distance_clause = f\"VectorDistance(c.{vector_field_name}, @vector)\"\n        elif search_type == SearchType.KEYWORD_HYBRID:\n            # Hybrid search: requires both a vector and keywords\n            params.append({\"name\": \"@keywords\", \"value\": values})\n            text_field = options.additional_property_name\n            if not text_field:\n                raise VectorStoreModelException(\"Hybrid search requires 'keyword_field_name' in options.\")\n            distance_clause = (\n                f\"RRF(VectorDistance(c.{vector_field_name}, @vector), FullTextScore(c.{text_field}, @keywords))\"\n            )\n        else:\n            raise VectorStoreModelException(f\"Search type '{search_type}' is not supported.\")\n        query = (\n            f\"SELECT TOP @top {select_clause}, \"  # nosec: B608\n            f\"{distance_clause} as {NOSQL_SCORE_PROPERTY_NAME} \"  # nosec: B608\n            \"FROM c \"\n            f\"{where_clauses}\"  # nosec: B608\n            f\"ORDER BY {distance_clause}\"  # nosec: B608\n        )\n\n        container_proxy = await self._get_container_proxy(self.collection_name, **kwargs)\n        try:\n            results = container_proxy.query_items(query, parameters=params)\n        except Exception as exc:\n            raise VectorSearchExecutionException(\"Failed to search items.\") from exc","sourceCodeStart":820,"sourceCodeEnd":856,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/azure_cosmos_db.py#L820-L856","documentation":"Raised by the Azure Cosmos DB NoSQL vector store when a KEYWORD_HYBRID search is requested but no keyword/text field is configured. The hybrid path builds an RRF() clause combining VectorDistance and FullTextScore(c.<text_field>, @keywords); FullTextScore needs a concrete text column to score against. Without a configured keyword field the SQL cannot be generated, so the store aborts before issuing the query. This is a VectorStoreModelException, signaling a misconfigured data model / options, not a transient runtime fault.","triggerScenarios":"Calling _inner_search (via the public search API) with search_type=SearchType.KEYWORD_HYBRID while VectorSearchOptions.additional_property_name is None or unset. This field (aliased as keyword_field_name) selects which string property FullTextScore runs against; if it is missing the check at azure_cosmos_db.py:836-838 fires.","commonSituations":"You added hybrid search to an existing vector-only collection but forgot to designate a text field for full-text indexing, or you reuse a VectorSearchOptions object that was built for a pure vector query. Also happens when the data model has no full-text-searchable text field defined, or after upgrading where the option key changed naming.","solutions":["Set the keyword field when building options: VectorSearchOptions(additional_property_name=\"description\") (or keyword_field_name alias), pointing at a text property that exists in your data model and is covered by a full-text policy/index.","Ensure that text field is declared in the record data model and that the container's indexing policy enables full-text search on it before issuing hybrid queries.","If you only need pure vector similarity, call search with SearchType.VECTOR instead of KEYWORD_HYBRID so the keyword field is not required."],"exampleFix":"// before\nresults = await store.search(vector, VectorSearchOptions(top=5))  # search_type defaults but hybrid keyword field missing\n// after\nresults = await store.search(\n    vector,\n    VectorSearchOptions(top=5, additional_property_name=\"description\"),\n)","handlingStrategy":"validation","validationCode":"opts = VectorSearchOptions(top=5, additional_property_name=\"description\")\nassert opts.additional_property_name, \"Hybrid search requires a keyword field\"\n# only then:\nresults = await store.search(vector, options=opts)","typeGuard":"def is_hybrid_ready(store, options: VectorSearchOptions) -> bool:\n    return (\n        options.additional_property_name is not None\n        and options.additional_property_name in store.definition.storage_names\n    )","tryCatchPattern":null,"preventionTips":["Always set additional_property_name when using KEYWORD_HYBRID search type.","Confirm the keyword field is declared in the data model and indexed for full-text search.","Reuse a dedicated options builder for hybrid vs vector search so the keyword field is never forgotten."],"tags":["azure-cosmos-db","vector-search","configuration","hybrid-search"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}