From 7f5f3227d7d9192018ca2ed2efd8f0b7a1fbfdd5 Mon Sep 17 00:00:00 2001 From: RoyVivat Date: Wed, 18 Mar 2026 16:34:05 -0700 Subject: [PATCH] Updated to handle and test edge case where id is empty after bucket name. --- litellm/utils.py | 6 ++++-- tests/test_litellm/integrations/test_s3_v2.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/litellm/utils.py b/litellm/utils.py index ef67ea74894..48b0bd87fc9 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -7402,9 +7402,11 @@ def print_args_passed_to_litellm(original_function, args, kwargs): def get_logging_id(start_time, response_obj): try: raw_id = response_obj.get("id") or "" - # Batch API IDs may be S3 URIs (e.g. "s3://bucket/key"). Strip the scheme and bucket, keeping only the object key to use as the log ID. + # Batch API IDs may be S3 URIs (e.g. "s3://bucket/key"). Strip the + # scheme and bucket, keeping only the object key to use as the log ID. if "://" in raw_id: - safe_id = raw_id.split("://", 1)[1].split("/", 1)[-1].replace("/", "-") + after_scheme = raw_id.split("://", 1)[1] # "bucket/key" or "bucket" + safe_id = after_scheme.split("/", 1)[1].replace("/", "-") if "/" in after_scheme else "" else: safe_id = raw_id response_id = "time-" + start_time.strftime("%H-%M-%S-%f") + "_" + safe_id diff --git a/tests/test_litellm/integrations/test_s3_v2.py b/tests/test_litellm/integrations/test_s3_v2.py index 7dc25043fd5..ce69dad3887 100644 --- a/tests/test_litellm/integrations/test_s3_v2.py +++ b/tests/test_litellm/integrations/test_s3_v2.py @@ -687,6 +687,24 @@ def test_get_logging_id_normal_id_unchanged(): assert result == "time-17-40-11-901585_chatcmpl-abc123" +def test_get_logging_id_bucket_only_uri_does_not_leak_bucket_name(): + """s3://my-bucket with no object key must not leak the bucket name into the log path.""" + start_time = datetime(2026, 3, 9, 17, 40, 11, 901585) + response_obj = {"id": "s3://my-bucket"} + result = get_logging_id(start_time, response_obj) + assert "my-bucket" not in result, "Bucket name must not appear in log ID" + assert "://" not in result + + +def test_get_logging_id_none_id_does_not_raise(): + """None id must not raise and must return a usable (non-None) string.""" + start_time = datetime(2026, 3, 9, 17, 40, 11, 901585) + response_obj = {"id": None} + result = get_logging_id(start_time, response_obj) + assert result is not None + assert result.startswith("time-17-40-11-901585_") + + def test_get_logging_id_s3_uri_safe_for_url_path(): """The sanitized log ID must be embeddable in an S3 object key URL without creating a malformed path.""" start_time = datetime(2026, 3, 9, 17, 40, 11, 901585)