open-telemetry / open-telemetry/opentelemetry-python-genai

util-genai: GenAIInvocation._finish detaches its context token unguarded; async LangChain runs log a traceback per invocation

Open
#677 0 comments 0 reactions 0 assignees View on GitHub

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

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 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.