traceloop / traceloop/openllmetry

๐Ÿ› Bug Report: `langgraph_utils.extract_graph_structure` drops `gen_ai.workflow.nodes` when node ids are str subclasses

Open Beginner friendly
#4,447 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
7.4k
Forks
1.1k
Avg merge
8d 14h
Merged PRs (30d)
2

Description

Which component is this bug for?

Langchain Instrumentation

๐Ÿ“œ Description

LangGraph permits StrEnum node ids (graph.add_node(MyEnum.X, ...)). extract_graph_structure appends them raw (nodes.append(node_id)), and patch.py passes the list to set_attribute. OTel's _clean_attribute validates sequence elements with type(element) not in (bool, str, bytes, int, float). An exact-type check. So a str subclass is rejected, the entire gen_ai.workflow.nodes attribute is dropped, and opentelemetry.attributes logs a WARNING on every graph invocation.

๐Ÿ‘Ÿ Reproduction steps
from enum import StrEnum
from typing import TypedDict

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter

# A recording TracerProvider is required, otherwise spans are no-ops
# and set_attribute never runs OTel's attribute validation.
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(provider)

from opentelemetry.instrumentation.langchain import LangchainInstrumentor
LangchainInstrumentor().instrument()

from langgraph.graph import StateGraph, START, END


class NodeName(StrEnum):          # node ids are a str subclass
    PARSE = "parse"
    CLASSIFY = "classify"


class State(TypedDict):
    value: int


graph = StateGraph(State)
graph.add_node(NodeName.PARSE, lambda s: {"value": 1})       # StrEnum member as node id
graph.add_node(NodeName.CLASSIFY, lambda s: {"value": 2})
graph.add_edge(START, NodeName.PARSE)
graph.add_edge(NodeName.PARSE, NodeName.CLASSIFY)
graph.add_edge(NodeName.CLASSIFY, END)

graph.compile().invoke({"value": 0})
๐Ÿ‘ Expected behavior

gen_ai.workflow.nodes should be populated with the node names as plain strings, with no warning. LangGraph officially allows StrEnum (and other str-subclass) node ids, so the instrumentation should record them the same way it records string ids.

๐Ÿ‘Ž Actual Behavior with Screenshots
WARNING opentelemetry.attributes: Invalid type NodeName in attribute
'gen_ai.workflow.nodes' value sequence. Expected one of
['bool', 'str', 'bytes', 'int', 'float'] or None
๐Ÿค– Python Version

3.14

๐Ÿ“ƒ Provide any additional context for the Bug.

Root cause seems to be in packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/langgraph_utils.py

๐Ÿ‘€ Have you spent some time to check if this bug has been raised before?
  • I checked and didn't find similar issue
Are you willing to submit PR?

None

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up โ€” it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/langgraph_utils.py and run the provided StrEnum reproduction with a recording TracerProvider. Trace how node IDs reach the span attribute, then verify that gen_ai.workflow.nodes contains plain strings and that the OpenTelemetry warning is absent.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
observability-sre
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
85/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.