fix(langchain): detach existing SpanHolder token before overwrite in _create_llm_span#3958
Conversation
…_create_llm_span Closes traceloop#3957 When _create_llm_span() is called for a run_id that already has an entry in self.spans, the old holder's token was lost without being detached, leaving an orphaned context_api.attach() on the OTel context stack. This is the same class of bug as traceloop#3526 / traceloop#3807. Defensively detach the existing holder's token before replacing the entry.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes #3957
feat(instrumentation): ...orfix(instrumentation): ....What
In
_create_llm_span(), when aSpanHolderalready exists for a givenrun_id, the old entry was being replaced directly. The previous holder'stoken(fromcontext_api.attach(set_value(SUPPRESS_LANGUAGE_MODEL_INSTRUMENTATION_KEY, True))) was dropped on the floor without ever being detached, leaving an orphaned entry on the OTel context stack.This is the same class of bug as the ones fixed in #3526 and #3807, just on a different code path. It was flagged during review of #3807 and tracked separately in #3957.
Fix
Before overwriting
self.spans[run_id], check if an existing holder is present and detach its token through the existing_safe_detach_context()helper.Scoped strictly to
_create_llm_span()as described in #3957. The same pattern exists in_create_span()and_create_task_span(), but those were not called out in the issue, so leaving them out of this PR to keep it tight.Tests
No new tests added — this is a defensive fix for a race between the runtime overwriting the registry entry and the old token remaining attached, which is hard to cover with cassette-based tests. Happy to add one if a maintainer suggests a good angle.
AI Disclosure
Took help of an AI tool to draft the fix and this description.
Summary by CodeRabbit