diff --git a/litellm/integrations/langfuse/langfuse_sdk.py b/litellm/integrations/langfuse/langfuse_sdk.py index 1d4979e0924..e6713ce2d86 100644 --- a/litellm/integrations/langfuse/langfuse_sdk.py +++ b/litellm/integrations/langfuse/langfuse_sdk.py @@ -44,8 +44,8 @@ __all__ = ( AS_ROOT_ATTRIBUTE: Final = "langfuse.internal.as_root" PUBLIC_ATTRIBUTE: Final = "langfuse.trace.public" RELEASE_ATTRIBUTE: Final = "langfuse.release" -_TRACE_ID_PATTERN: Final = re.compile(r"^[0-9a-f]{32}$") -_OBSERVATION_ID_PATTERN: Final = re.compile(r"^[0-9a-f]{16}$") +_TRACE_ID_PATTERN: Final = re.compile(r"^(?=.*[1-9a-f])[0-9a-f]{32}$") +_OBSERVATION_ID_PATTERN: Final = re.compile(r"^(?=.*[1-9a-f])[0-9a-f]{16}$") def to_unix_nanos(value: datetime | float | None) -> int | None: diff --git a/tests/test_litellm/integrations/langfuse/test_langfuse_sdk.py b/tests/test_litellm/integrations/langfuse/test_langfuse_sdk.py index b980768657c..de75aacd95f 100644 --- a/tests/test_litellm/integrations/langfuse/test_langfuse_sdk.py +++ b/tests/test_litellm/integrations/langfuse/test_langfuse_sdk.py @@ -284,6 +284,17 @@ def test_non_string_observation_id_is_normalized(supplied): assert resolved == resolve_observation_id(supplied) +def test_all_zero_ids_are_hashed_instead_of_passed_through(): + zero_trace = "0" * 32 + zero_span = "0" * 16 + + assert resolve_trace_id(zero_trace) != zero_trace + assert resolve_trace_id(zero_trace) == resolve_trace_id(zero_trace) + assert int(resolve_trace_id(zero_trace), 16) != 0 + assert resolve_observation_id(zero_span) != zero_span + assert int(resolve_observation_id(zero_span), 16) != 0 + + def test_hyphen_only_trace_ids_are_deterministic(): assert resolve_trace_id("---") == resolve_trace_id("---")