From 8cedf2c196d2410ddc253920f7619f9fe4e9b08f Mon Sep 17 00:00:00 2001 From: lisry-1 <249596828+lisry-1@users.noreply.github.com> Date: Sat, 31 Oct 2026 15:18:02 +0800 Subject: [PATCH 1/2] fix(azure-cosmos): raise ValueError for empty session_id instead of generating orphan GUID _session_partition_key previously generated a fresh random GUID for every call when session_id was None/empty. This made save_messages(None, ...) write to partition A while get_messages(None) / clear(None) read partition B/C, silently orphaning the stored data. This also diverged from the Redis scoped and VectorStore providers, which reject an empty session_id. Align Cosmos with those providers by raising ValueError for a missing session_id, and update the regression test accordingly. --- .../_history_provider.py | 12 +++-------- .../tests/test_cosmos_history_provider.py | 21 ++++--------------- 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/python/packages/azure-cosmos/agent_framework_azure_cosmos/_history_provider.py b/python/packages/azure-cosmos/agent_framework_azure_cosmos/_history_provider.py index b62c5467ad8..0a6e2167bf6 100644 --- a/python/packages/azure-cosmos/agent_framework_azure_cosmos/_history_provider.py +++ b/python/packages/azure-cosmos/agent_framework_azure_cosmos/_history_provider.py @@ -300,12 +300,6 @@ async def _ensure_container_proxy(self) -> None: @staticmethod def _session_partition_key(session_id: str | None) -> str: - if session_id: - return session_id - - generated_session_id = str(uuid.uuid4()) - logger.warning( - "Received empty session_id; generated temporary session id '%s' for Cosmos partition key.", - generated_session_id, - ) - return generated_session_id + if not session_id: + raise ValueError("session_id must be a non-empty string.") + return session_id diff --git a/python/packages/azure-cosmos/tests/test_cosmos_history_provider.py b/python/packages/azure-cosmos/tests/test_cosmos_history_provider.py index 58461cd094a..3d9592302f6 100644 --- a/python/packages/azure-cosmos/tests/test_cosmos_history_provider.py +++ b/python/packages/azure-cosmos/tests/test_cosmos_history_provider.py @@ -189,26 +189,13 @@ async def test_empty_returns_empty(self, mock_container: MagicMock) -> None: assert messages == [] - async def test_none_session_id_generates_guid_partition_key( - self, mock_container: MagicMock, caplog: pytest.LogCaptureFixture - ) -> None: - mock_container.query_items.return_value = _to_async_iter([]) - + async def test_none_session_id_raises_value_error(self, mock_container: MagicMock) -> None: provider = CosmosHistoryProvider(source_id="mem", container_client=mock_container) - with caplog.at_level("WARNING"): + + with pytest.raises(ValueError, match="session_id"): await provider.get_messages(None) - query_kwargs = mock_container.query_items.call_args.kwargs - session_key = query_kwargs["partition_key"] - assert isinstance(session_key, str) - assert session_key != "" - assert session_key != "default" - uuid.UUID(session_key) - assert query_kwargs["parameters"] == [ - {"name": "@session_id", "value": session_key}, - {"name": "@source_id", "value": "mem"}, - ] - assert "Received empty session_id" in caplog.text + mock_container.query_items.assert_not_called() async def test_skips_non_dict_message_payload(self, mock_container: MagicMock) -> None: mock_container.query_items.return_value = _to_async_iter([{"message": "bad"}, {"message": None}]) From d28c798a43b553d67e13288805306cb7f6d2185d Mon Sep 17 00:00:00 2001 From: lisry-1 <249596828+lisry-1@users.noreply.github.com> Date: Sun, 1 Nov 2026 20:29:17 +0800 Subject: [PATCH 2/2] test(azure-cosmos): cover empty-string session id rejection Parameterize the missing-session-id test to cover both None and the empty string, matching the non-empty guard in _session_partition_key. --- .../azure-cosmos/tests/test_cosmos_history_provider.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/python/packages/azure-cosmos/tests/test_cosmos_history_provider.py b/python/packages/azure-cosmos/tests/test_cosmos_history_provider.py index 3d9592302f6..3451f7b304f 100644 --- a/python/packages/azure-cosmos/tests/test_cosmos_history_provider.py +++ b/python/packages/azure-cosmos/tests/test_cosmos_history_provider.py @@ -189,11 +189,14 @@ async def test_empty_returns_empty(self, mock_container: MagicMock) -> None: assert messages == [] - async def test_none_session_id_raises_value_error(self, mock_container: MagicMock) -> None: + @pytest.mark.parametrize("session_id", [None, ""], ids=["none", "empty"]) + async def test_missing_session_id_raises_value_error( + self, mock_container: MagicMock, session_id: str | None + ) -> None: provider = CosmosHistoryProvider(source_id="mem", container_client=mock_container) with pytest.raises(ValueError, match="session_id"): - await provider.get_messages(None) + await provider.get_messages(session_id) mock_container.query_items.assert_not_called()