Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion langfuse/langchain/CallbackHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ def on_chain_start(
session_id=parsed_trace_attributes.get("session_id", None),
tags=parsed_trace_attributes.get("tags", None),
metadata=parsed_trace_attributes.get("metadata", None),
trace_name=parsed_trace_attributes.get("trace_name", None),
trace_name=parsed_trace_attributes.get("trace_name", span_name),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 When serialized carries no name information and the name kwarg is absent, get_langchain_run_name returns the sentinel string "<unknown>". With this change, "<unknown>" will now be propagated as the explicit trace name (it is non-None, so propagate_attributes won't filter it out and will write it into the OTel context). Before this PR the None default caused the trace_name attribute to be omitted entirely. Consider guarding against the sentinel so the pre-existing "no-name" behaviour is preserved for that edge case.

Suggested change
trace_name=parsed_trace_attributes.get("trace_name", span_name),
trace_name=parsed_trace_attributes.get(
"trace_name",
span_name if span_name != "<unknown>" else None,
),
Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/langchain/CallbackHandler.py
Line: 597

Comment:
When `serialized` carries no name information and the `name` kwarg is absent, `get_langchain_run_name` returns the sentinel string `"<unknown>"`. With this change, `"<unknown>"` will now be propagated as the explicit trace name (it is non-`None`, so `propagate_attributes` won't filter it out and will write it into the OTel context). Before this PR the `None` default caused the `trace_name` attribute to be omitted entirely. Consider guarding against the sentinel so the pre-existing "no-name" behaviour is preserved for that edge case.

```suggestion
                    trace_name=parsed_trace_attributes.get(
                        "trace_name",
                        span_name if span_name != "<unknown>" else None,
                    ),
```

How can I resolve this? If you propose a fix, please make it concise.

)

root_run_state = self._get_root_run_state(run_id)
Expand Down
23 changes: 22 additions & 1 deletion tests/unit/test_langchain.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import importlib
from contextvars import copy_context
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from uuid import uuid4

import pytest
Expand Down Expand Up @@ -276,6 +276,27 @@ def test_root_chain_exports_when_end_runs_in_copied_context(
otel_context.detach(context_token)


def test_root_chain_propagates_run_name_as_default_trace_name():
handler = CallbackHandler()
run_id = uuid4()
propagation_context_manager = MagicMock()

with patch.object(
callback_handler_module,
"propagate_attributes",
return_value=propagation_context_manager,
) as mock_propagate:
handler.on_chain_start(
{"id": ["langgraph", "Pregel"]},
{"messages": ["hello"]},
run_id=run_id,
name="my-agent",
)

mock_propagate.assert_called_once()
assert mock_propagate.call_args.kwargs["trace_name"] == "my-agent"


def test_control_flow_errors_use_default_level_and_keep_status_message(
langfuse_memory_client, get_span, monkeypatch
):
Expand Down