microsoft/semantic-kernel · error · NotImplementedError

Get without keys is not yet implemented.

Error message

Get without keys is not yet implemented.

What it means

CosmosNoSqlCollection._inner_get requires either explicit keys or a None options value. Passing GetFilteredRecordOptions without keys is not supported by this connector, so it raises NotImplementedError. With keys=None and options=None it returns None (no-op).

Source

Thrown at python/semantic_kernel/connectors/azure_cosmos_db.py:751

    async def _inner_upsert(
        self,
        records: Sequence[Any],
        **kwargs: Any,
    ) -> Sequence[TNoSQLKey]:
        container_proxy = await self._get_container_proxy(self.collection_name, **kwargs)
        results = await asyncio.gather(*(container_proxy.upsert_item(record) for record in records))
        return [result[COSMOS_ITEM_ID_PROPERTY_NAME] for result in results]

    @override
    async def _inner_get(  # type: ignore
        self,
        keys: Sequence[TNoSQLKey] | None = None,
        options: GetFilteredRecordOptions | None = None,
        **kwargs: Any,
    ) -> Sequence[Any] | None:
        if not keys:
            if options is not None:
                raise NotImplementedError("Get without keys is not yet implemented.")
            return None
        include_vectors = kwargs.pop("include_vectors", False)
        query = (
            f"SELECT {self._build_select_clause(include_vectors)} FROM c WHERE "  # nosec: B608
            f"c.id IN ({', '.join([f'@id{i}' for i in range(len(keys))])})"  # nosec: B608
        )  # nosec: B608
        parameters: list[dict[str, Any]] = [{"name": f"@id{i}", "value": _get_key(key)} for i, key in enumerate(keys)]

        container_proxy = await self._get_container_proxy(self.collection_name, **kwargs)
        return [item async for item in container_proxy.query_items(query=query, parameters=parameters)]

    @override
    async def _inner_delete(self, keys: Sequence[TNoSQLKey], **kwargs: Any) -> None:  # type: ignore
        container_proxy = await self._get_container_proxy(self.collection_name, **kwargs)
        results = await asyncio.gather(
            *[container_proxy.delete_item(item=_get_key(key), partition_key=_get_partition_key(key)) for key in keys],
            return_exceptions=True,
        )

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Always pass keys= to collection.get on CosmosNoSqlCollection.
  2. For filtered queries, use the search/query path instead of get.
  3. If you only need existence, pass keys and check the returned sequence.

Example fix

// before
rows = await collection.get(options=GetFilteredRecordOptions(...))
// after
rows = await collection.get(keys=["id1","id2"])
Defensive patterns

Strategy: validation

Validate before calling

if not keys and options is not None:
    raise ValueError("CosmosNoSqlCollection.get requires keys when options are provided")
rows = await collection.get(keys=keys)

Type guard

def is_valid_get_call(keys, options) -> bool:
    return bool(keys) or options is None

Prevention

When it happens

Trigger: Raised in _inner_get when keys is falsy AND options is not None. Triggered when a caller calls collection.get(options=GetFilteredRecordOptions(...)) without supplying keys, expecting filtered scan behavior the NoSQL connector does not implement.

Common situations: Assuming filtered-record scan works the same as in another connector (e.g. one that supports query-by-filter). Porting code that used get(options=...) elsewhere. Misunderstanding that this collection is key-oriented.

Related errors


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