fix(langchain): load LangChainTracer synchronously to avoid span loss#169
Draft
JacksonWeber wants to merge 1 commit into
Draft
fix(langchain): load LangChainTracer synchronously to avoid span loss#169JacksonWeber wants to merge 1 commit into
JacksonWeber wants to merge 1 commit into
Conversation
The previous lazy `import("./tracer.js")` resolved on a later microtask, so any `_configureSync` call that landed before it resolved (typically the first compiled-StateGraph `invoke` after distro startup) silently fell through with no tracer attached. The outer `invoke_agent LangGraph` wrapper span was dropped and the trace fragmented into multiple roots.
Bind LangChainTracer via a static import and field initializer, and remove the silent skip branch in the wrapped `_configureSync`. Safe because by the time `patch()` runs, `@langchain/core/callbacks/manager` is already loaded (it is the `module` argument).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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
The LangChain instrumentor was loading
LangChainTracerlazily viavoid import("./tracer.js").then(...). Because the dynamic import resolves on a later microtask, anyCallbackManager._configureSynccall that fired in the window betweenpatch()running and the import resolving silently fell through with no tracer attached:In practice the first compiled-
StateGraphinvoke(...)after distro startup reliably lands in that window. Its outer chain run never gets a tracer, so the outermostinvoke_agent LangGraphwrapper span is never emitted, the inner agent/chat spans become trace roots, and the App Insights end-to-end view splits a single workflow run into multiple unrelated traces.Fix
LangChainTracerfrom a type-only lazyimport()to a static value import._tracerCtor = LangChainTracerat field-declaration time so it is defined beforepatch()ever runs.if (_tracerCtor) ... else { ...skipping }branch in the wrapped_configureSync— the tracer is now guaranteed to be present.The static import is safe here because by the time
patch()runs,@langchain/core/callbacks/manageris already loaded (it is the verymoduleargument), so transitively importingBaseTracerno longer bypasses any instrumentation hooks.Verification
Reproduced against the public LangChain + Microsoft OTEL distro NodeJs repro at https://github.com/tokaplan/testrepo/tree/master/LangChain%20with%20Microsoft%20OTEL%20distro/NodeJs.
Before: the first protocol exercised (typically
completions/AzureChatOpenAI) was missing itsinvoke_agent LangGraphouter span; reordering the protocols showed the missing wrapper followed whichever workflow ran first — confirming the cause was an init race, not anything client-specific.After (built from this branch): all three protocols emit the outer
invoke_agent LangGraphwrapper span on the sametraceIdas the innerMainWeatherAgent/chatspans, and noLangChainTracer not yet loaded, skippingdebug messages are emitted.npm run lintandtsc -p tsconfig.src.json --noEmitboth clean.