fix(langchain): propagate run name as trace name#1743
Open
sjsjsjjs534 wants to merge 1 commit into
Open
Conversation
| 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), |
Contributor
There was a problem hiding this 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.
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.|
zhangsixiao seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
langfuse_trace_namemetadata as the override when providedFixes #1602
Tests
Greptile Summary
This PR fixes #1602 by propagating the LangChain root run name as the default trace name in Langfuse when no explicit
langfuse_trace_nameis provided in metadata.on_chain_start:parsed_trace_attributes.get(\"trace_name\", None)→parsed_trace_attributes.get(\"trace_name\", span_name), so the LangChain run name flows through as the trace name unless a user-specified override exists.propagate_attributesand asserts thattrace_nameequals thenamekwarg passed toon_chain_start, covering the primary regression path.Confidence Score: 4/5
The fix is minimal and correct — it threads the LangChain run name through to Langfuse when no explicit override is provided, and does not touch any other code paths.
The core change is a one-line default swap that works as described. The only wrinkle is that
get_langchain_run_namecan return"<unknown>"as a sentinel, and that sentinel will now be written into the OTel propagation context as an explicit trace name instead of being silently omitted. This is a narrow edge case (unnamed chains with no serialized id), but the behaviour change is observable in Langfuse traces.langfuse/langchain/CallbackHandler.py — specifically the
"<unknown>"sentinel path inget_langchain_run_nameFlowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A["on_chain_start called\n(parent_run_id is None)"] --> B["get_langchain_run_name()\n→ span_name"] B --> C["_parse_langfuse_trace_attributes(metadata, tags)\n→ parsed_trace_attributes"] C --> D{langfuse_trace_name\nin metadata?} D -- "Yes" --> E["trace_name = parsed_trace_attributes['trace_name']\n(explicit override)"] D -- "No (before PR)" --> F["trace_name = None\n(no name propagated)"] D -- "No (after PR)" --> G["trace_name = span_name\n(LangChain run name)"] G --> H{span_name resolved?} H -- "kwargs['name'] set" --> I["trace_name = kwargs['name']"] H -- "serialized['name'] set" --> J["trace_name = serialized['name']"] H -- "serialized['id'] set" --> K["trace_name = serialized['id'][-1]"] H -- "nothing set" --> L["trace_name = 'unknown'"] E --> M["propagate_attributes(trace_name=...)"] F --> N["propagate_attributes(trace_name=None)\n→ filtered out, no name set"] I --> M J --> M K --> M L --> M%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% flowchart TD A["on_chain_start called\n(parent_run_id is None)"] --> B["get_langchain_run_name()\n→ span_name"] B --> C["_parse_langfuse_trace_attributes(metadata, tags)\n→ parsed_trace_attributes"] C --> D{langfuse_trace_name\nin metadata?} D -- "Yes" --> E["trace_name = parsed_trace_attributes['trace_name']\n(explicit override)"] D -- "No (before PR)" --> F["trace_name = None\n(no name propagated)"] D -- "No (after PR)" --> G["trace_name = span_name\n(LangChain run name)"] G --> H{span_name resolved?} H -- "kwargs['name'] set" --> I["trace_name = kwargs['name']"] H -- "serialized['name'] set" --> J["trace_name = serialized['name']"] H -- "serialized['id'] set" --> K["trace_name = serialized['id'][-1]"] H -- "nothing set" --> L["trace_name = 'unknown'"] E --> M["propagate_attributes(trace_name=...)"] F --> N["propagate_attributes(trace_name=None)\n→ filtered out, no name set"] I --> M J --> M K --> M L --> MPrompt To Fix All With AI
Reviews (1): Last reviewed commit: "fix langchain trace name propagation" | Re-trigger Greptile