From 13d12ae4b841e25a0368e9d0ea58ce03957fd99a Mon Sep 17 00:00:00 2001 From: yucheng Date: Thu, 17 Sep 2026 03:23:10 +0000 Subject: [PATCH] fix(langfuse): warn about ignored UPSTREAM_LANGFUSE_* on the shared client init path too Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm/integrations/langfuse/langfuse.py | 14 +++++++++---- .../langfuse/langfuse_prompt_management.py | 2 ++ .../test_langfuse_prompt_management.py | 20 +++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/litellm/integrations/langfuse/langfuse.py b/litellm/integrations/langfuse/langfuse.py index 2311575c023..4b55c1eef76 100644 --- a/litellm/integrations/langfuse/langfuse.py +++ b/litellm/integrations/langfuse/langfuse.py @@ -307,6 +307,15 @@ def resolve_langfuse_credentials( return public_key, secret_key, resolved_host +def warn_if_upstream_langfuse_configured() -> None: + if os.getenv("UPSTREAM_LANGFUSE_SECRET_KEY") is None: + return + verbose_logger.warning( + "UPSTREAM_LANGFUSE_* is no longer supported: the langfuse callback moved to SDK v4, " + "which has no second ingestion client. The values are ignored." + ) + + def parse_langfuse_debug(raw_value: str | None) -> bool: """Parse the LANGFUSE_DEBUG value into the boolean flag the langfuse client expects.""" return raw_value is not None and raw_value.strip().lower() in ("true", "1") @@ -393,11 +402,8 @@ class LangFuseLogger: except Exception: verbose_logger.debug("Langfuse project id unavailable, alerting links will omit it") + warn_if_upstream_langfuse_configured() if os.getenv("UPSTREAM_LANGFUSE_SECRET_KEY") is not None: - verbose_logger.warning( - "UPSTREAM_LANGFUSE_* is no longer supported: the langfuse callback moved to SDK v4, " - "which has no second ingestion client. The values are ignored." - ) self.upstream_langfuse_secret_key = os.getenv("UPSTREAM_LANGFUSE_SECRET_KEY") self.upstream_langfuse_public_key = os.getenv("UPSTREAM_LANGFUSE_PUBLIC_KEY") self.upstream_langfuse_host = os.getenv("UPSTREAM_LANGFUSE_HOST") diff --git a/litellm/integrations/langfuse/langfuse_prompt_management.py b/litellm/integrations/langfuse/langfuse_prompt_management.py index d8b3689eb0a..9982f48616a 100644 --- a/litellm/integrations/langfuse/langfuse_prompt_management.py +++ b/litellm/integrations/langfuse/langfuse_prompt_management.py @@ -25,6 +25,7 @@ from .langfuse import ( parse_langfuse_debug, raise_if_unsupported_langfuse_version, resolve_langfuse_credentials, + warn_if_upstream_langfuse_configured, ) from .langfuse_handler import LangFuseHandler from .langfuse_mock_client import create_mock_langfuse_client, should_use_langfuse_mock @@ -103,6 +104,7 @@ def langfuse_client_init( } raise_if_unsupported_langfuse_version(installed_langfuse_version()) + warn_if_upstream_langfuse_configured() import httpx diff --git a/tests/test_litellm/integrations/langfuse/test_langfuse_prompt_management.py b/tests/test_litellm/integrations/langfuse/test_langfuse_prompt_management.py index b1997b654ac..f7c09e4ad1e 100644 --- a/tests/test_litellm/integrations/langfuse/test_langfuse_prompt_management.py +++ b/tests/test_litellm/integrations/langfuse/test_langfuse_prompt_management.py @@ -134,6 +134,26 @@ def test_langfuse_client_init_resolves_deployment_environment(monkeypatch, env_v assert _RecordingLangfuseForEnv.last_environment == expected +def test_langfuse_client_init_warns_that_upstream_langfuse_is_ignored(monkeypatch, caplog): + """The YAML `callbacks: ["langfuse"]` path builds its client here, not through LangFuseLogger.__init__, + so an operator who still sets UPSTREAM_LANGFUSE_* must get the same startup warning on this path.""" + monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "pk-test") + monkeypatch.setenv("LANGFUSE_SECRET_KEY", "sk-test") + monkeypatch.setenv("LANGFUSE_HOST", "https://test.langfuse.com") + monkeypatch.setenv("UPSTREAM_LANGFUSE_SECRET_KEY", "sk-upstream") + monkeypatch.setenv("UPSTREAM_LANGFUSE_HOST", "https://upstream.example") + with ( + patch( + "litellm.integrations.langfuse.langfuse_sdk.Langfuse", _RecordingLangfuseForEnv + ), # test-quality-ok: the ctor must be intercepted where acquire_langfuse_client resolves it; a real client spawns export threads + caplog.at_level("WARNING", logger="LiteLLM"), + ): + langfuse_client_init.cache_clear() + langfuse_client_init() + langfuse_client_init.cache_clear() + assert any("UPSTREAM_LANGFUSE_* is no longer supported" in record.getMessage() for record in caplog.records) + + def test_langfuse_client_init_mock_mode_makes_no_network_calls(monkeypatch): """LANGFUSE_MOCK promises full execution without egress.