microsoft/semantic-kernel · error · ValueError

vectorIndexes cannot be null or empty in the indexing_policy

Error message

vectorIndexes cannot be null or empty in the indexing_policy.

What it means

Raised in AzureCosmosDBNoSQLMemoryStore.__init__ when the provided indexing_policy dict has a 'vectorIndexes' key that is None or an empty list. Azure Cosmos DB NoSQL vector search requires at least one vector index definition (e.g. flat, diskANN) to perform ANN queries; without it the container cannot be created with vector capabilities. Note the code accesses indexing_policy["vectorIndexes"] directly, so a missing key produces a KeyError instead, and passing None for the whole indexing_policy produces a TypeError before this check.

Source

Thrown at python/semantic_kernel/connectors/memory_stores/azure_cosmosdb_no_sql/azure_cosmosdb_no_sql_memory_store.py:49

    container: ContainerProxy
    database_name: str = None
    partition_key: str = None
    vector_embedding_policy: dict[str, Any] | None = None
    indexing_policy: dict[str, Any] | None = None
    cosmos_container_properties: dict[str, Any] | None = None

    def __init__(
        self,
        cosmos_client: CosmosClient,
        database_name: str,
        partition_key: str,
        vector_embedding_policy: dict[str, Any] | None = None,
        indexing_policy: dict[str, Any] | None = None,
        cosmos_container_properties: dict[str, Any] | None = None,
    ):
        """Initializes a new instance of the AzureCosmosDBNoSQLMemoryStore class."""
        if indexing_policy["vectorIndexes"] is None or len(indexing_policy["vectorIndexes"]) == 0:
            raise ValueError("vectorIndexes cannot be null or empty in the indexing_policy.")
        if vector_embedding_policy is None or len(vector_embedding_policy["vectorEmbeddings"]) == 0:
            raise ValueError("vectorEmbeddings cannot be null or empty in the vector_embedding_policy.")

        self.cosmos_client = cosmos_client
        self.database_name = database_name
        self.partition_key = partition_key
        self.vector_embedding_policy = vector_embedding_policy
        self.indexing_policy = indexing_policy
        self.cosmos_container_properties = cosmos_container_properties

    @override
    async def create_collection(self, collection_name: str) -> None:
        # Create the database if it already doesn't exist
        self.database = await self.cosmos_client.create_database_if_not_exists(id=self.database_name)

        # Create the collection if it already doesn't exist
        self.container = await self.database.create_container_if_not_exists(
            id=collection_name,

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Supply an indexing_policy with a non-empty vectorIndexes list, e.g. indexing_policy={'indexingMode': 'consistent', 'includedPaths': [{'path': '/*'}], 'vectorIndexes': [{'path': '/embedding', 'type': 'diskANN'}]}.
  2. Ensure the vectorIndexes path matches the vectorEmbeddings path in vector_embedding_policy (line 50 checks that separately).
  3. If you pass None for indexing_policy intentionally, note the current code does NOT guard against it — you must always pass a fully-formed dict.
  4. Consider migrating to the non-deprecated AzureCosmosDBNoSQLStore / Collection classes as indicated by the @deprecated marker on this class.

Example fix

// before
store = AzureCosmosDBNoSQLMemoryStore(
    cosmos_client=client,
    database_name='db',
    partition_key='/pk',
    vector_embedding_policy={'vectorEmbeddings': [...]},
    indexing_policy={'vectorIndexes': []},  # triggers ValueError
)
// after
indexing_policy = {
    'indexingMode': 'consistent',
    'includedPaths': [{'path': '/*'}],
    'vectorIndexes': [{'path': '/embedding', 'type': 'diskANN'}],
}
store = AzureCosmosDBNoSQLMemoryStore(
    cosmos_client=client,
    database_name='db',
    partition_key='/pk',
    vector_embedding_policy={'vectorEmbeddings': [...]},
    indexing_policy=indexing_policy,
)
Defensive patterns

Strategy: validation

Validate before calling

def validate_indexing_policy(policy: dict | None) -> None:
    if policy is None:
        raise ValueError('indexing_policy must not be None')
    vi = policy.get('vectorIndexes')
    if vi is None or len(vi) == 0:
        raise ValueError('indexing_policy["vectorIndexes"] must be a non-empty list')

# call before constructing the store
validate_indexing_policy(indexing_policy)

Type guard

from typing import Any

def is_valid_indexing_policy(policy: Any) -> bool:
    return (
        isinstance(policy, dict)
        and isinstance(policy.get('vectorIndexes'), list)
        and len(policy['vectorIndexes']) > 0
    )

Try / catch

try:
    store = AzureCosmosDBNoSQLMemoryStore(..., indexing_policy=indexing_policy)
except ValueError as e:
    logging.error('Invalid indexing policy: %s', e)
    raise

Prevention

When it happens

Trigger: Constructing AzureCosmosDBNoSQLMemoryStore with indexing_policy={'vectorIndexes': None} or indexing_policy={'vectorIndexes': []}. The check at line 48 runs unconditionally in __init__, so any instantiation path that passes a dict lacking a populated vectorIndexes array hits it. If indexing_policy is left as the default None, a TypeError ('NoneType' is not subscriptable) fires first on the same line.

Common situations: Copying a minimal Azure Cosmos config snippet that omits the vectorIndexes block. Migrating from the newer AzureCosmosDBNoSQLStore API where the policy shape changed. Providing an indexing_policy dict built from a template that left vectorIndexes as a placeholder empty list.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/186bcc3162124bf2. Report an issue: GitHub.