open-telemetry / open-telemetry/opentelemetry-python-genai
util-genai: GenAIInvocation._finish detaches its context token unguarded; async LangChain runs log a traceback per invocation
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 39
- Forks
- 63
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 175
Description
Version: opentelemetry-util-genai 1.1b0 (_invocation.py:199).
What happens. _start attaches the invocation span to the current context and stores the
token; _finish calls detach(context_token) inside a bare try/except Exception: pass, but the
call it wraps is opentelemetry.context.detach, which itself catches the underlying ValueError
and logs Failed to detach context with a traceback at ERROR level. When the invocation is
started and stopped in different contextvars contexts — every async LangGraph run, where the
on_chain_start and on_chain_end callbacks execute in different tasks — one traceback is
logged per graph invocation, and the ended workflow span remains the current span in the calling
task.
Reproduce. A LangGraph StateGraph with one node, invoked with await graph.ainvoke(...)
under the official LangChain instrumentation with a TelemetryHandler; watch the
opentelemetry.context logger.
Suggested fix. Detach only when the token was created in the current context (compare
contextvars.copy_context() identity or catch ValueError before the API logs it), or give the
invocation an explicit "end without detach" path for callers that cannot guarantee the same
context. Consider making the log level DEBUG for this specific mismatch, since the span itself is
unaffected.
Downstream workaround (forgehawk SDK). A counting logging.Filter on the opentelemetry.context logger,
installed by forgehawk.init() and reported once through the SDK's own log and
forgehawk.status()["suppressed_detach_errors"] (sdk/python/src/forgehawk/_otel_noise.py).
Found while building the forgehawk Python SDK (ZioSec) on top of opentelemetry-util-genai; happy to open a PR for the suggested fix if maintainers agree with the direction.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at opentelemetry-util-genai/_invocation.py:199 and inspect how _start stores the context token and how _finish detaches it. Reproduce the issue with a one-node LangGraph StateGraph using await graph.ainvoke(...) and the official LangChain instrumentation with TelemetryHandler. Done means async invocations no longer emit an ERROR traceback and the ended workflow span is not left current in the calling task.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- observability
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 67/100