From ce17fa871f124d51b024a13e82de4bf6fa88bfa4 Mon Sep 17 00:00:00 2001 From: Rachit Mehta Date: Mon, 16 Mar 2026 09:57:29 -0400 Subject: [PATCH] fix s3session manager bug --- src/strands/session/s3_session_manager.py | 5 +++- .../session/test_s3_session_manager.py | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/strands/session/s3_session_manager.py b/src/strands/session/s3_session_manager.py index 8d557e81c..fad5e4fd0 100644 --- a/src/strands/session/s3_session_manager.py +++ b/src/strands/session/s3_session_manager.py @@ -95,7 +95,10 @@ def _get_session_path(self, session_id: str) -> str: ValueError: If session id contains a path separator. """ session_id = _identifier.validate(session_id, _identifier.Identifier.SESSION) - return f"{self.prefix}/{SESSION_PREFIX}{session_id}/" + prefix = self.prefix.strip("/") + if prefix: + return f"{prefix}/{SESSION_PREFIX}{session_id}/" + return f"{SESSION_PREFIX}{session_id}/" def _get_agent_path(self, session_id: str, agent_id: str) -> str: """Get agent S3 prefix. diff --git a/tests/strands/session/test_s3_session_manager.py b/tests/strands/session/test_s3_session_manager.py index c1c89da5b..29bc97ab5 100644 --- a/tests/strands/session/test_s3_session_manager.py +++ b/tests/strands/session/test_s3_session_manager.py @@ -89,6 +89,17 @@ def test_init_s3_session_manager_with_existing_user_agent(mocked_aws, s3_bucket) assert "strands-agents" in session_manager.client.meta.config.user_agent_extra +def test_empty_prefix_session_roundtrip(mocked_aws, s3_bucket, sample_session, sample_agent): + """Test that session data can be written and read back with default empty prefix.""" + manager = S3SessionManager(session_id="test", bucket=s3_bucket, prefix="", region_name="us-west-2") + manager.create_session(sample_session) + manager.create_agent(sample_session.session_id, sample_agent) + + result = manager.read_agent(sample_session.session_id, sample_agent.agent_id) + assert result is not None + assert result.agent_id == sample_agent.agent_id + + def test_create_session(s3_manager, sample_session): """Test creating a session in S3.""" result = s3_manager.create_session(sample_session) @@ -369,6 +380,24 @@ def test_update_nonexistent_message(s3_manager, sample_session, sample_agent, sa s3_manager.update_message(sample_session.session_id, sample_agent.agent_id, sample_message) +@pytest.mark.parametrize( + "prefix, expected_path", + [ + ("", "session_test-id/"), + ("sessions", "sessions/session_test-id/"), + ("sessions/", "sessions/session_test-id/"), + ("/sessions", "sessions/session_test-id/"), + ("/sessions/", "sessions/session_test-id/"), + ("a/b/c", "a/b/c/session_test-id/"), + ("a/b/c/", "a/b/c/session_test-id/"), + ], +) +def test__get_session_path_prefix_normalization(mocked_aws, s3_bucket, prefix, expected_path): + """Test that _get_session_path normalizes prefix to avoid leading or double slashes.""" + manager = S3SessionManager(session_id="test", bucket=s3_bucket, prefix=prefix, region_name="us-west-2") + assert manager._get_session_path("test-id") == expected_path + + @pytest.mark.parametrize( "session_id", [