Skip to content

Langchain Integration adds redundant callbacks #4443

Open
@mshavliuk

Description

@mshavliuk

How do you use Sentry?

Sentry Saas (sentry.io)

Version

2.27.0

Steps to Reproduce

When I configure the SentryLangchainCallback instance for invoke call I expect Sentry langchain integration not to create another instance of the same callback.

To reproduce the issue run code with breakpoints inside _wrap_configure:

import os
import sentry_sdk
from langchain_aws import ChatBedrockConverse
from langchain_core.runnables import RunnableConfig
from sentry_sdk.integrations.langchain import LangchainIntegration, SentryLangchainCallback

sentry_sdk.init(
    dsn=os.environ["SENTRY_DSN"],
    environment="localhost",
    traces_sample_rate=1.0,
    integrations=[LangchainIntegration()],
)

llm = ChatBedrockConverse(
    region_name="eu-west-1",
    aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
    aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],
    model="eu.amazon.nova-lite-v1:0",
    # intentionally invalid config to trigger error
    max_tokens=1,
    additional_model_request_fields={"inferenceConfig": {"topK": 0}},
)

config = RunnableConfig(callbacks=[SentryLangchainCallback(max_span_map_size=100, include_prompts=True)])
llm.invoke('hello', config)

Installed dependencies:

annotated-types==0.7.0
anyio==4.9.0
boto3==1.38.22
botocore==1.38.22
certifi==2025.4.26
charset-normalizer==3.4.2
h11==0.16.0
httpcore==1.0.9
httpx==0.28.1
idna==3.10
jmespath==1.0.1
jsonpatch==1.33
jsonpointer==3.0.0
langchain-aws==0.2.18
langchain-core==0.3.55
langsmith==0.3.42
numpy==2.2.6
orjson==3.10.18
packaging==24.2
pydantic==2.11.5
pydantic_core==2.33.2
python-dateutil==2.9.0.post0
PyYAML==6.0.2
requests==2.32.3
requests-toolbelt==1.0.0
s3transfer==0.13.0
sentry-sdk==2.27.0
six==1.17.0
sniffio==1.3.1
tenacity==9.1.2
typing-inspection==0.4.1
typing_extensions==4.13.2
urllib3==2.4.0
zstandard==0.23.0

Expected Result

I expect Sentry not to create another instance of the same callback handler.

Actual Result

Sentry integration creates a new instance of SentryLangchainCallback and attaches it to the chain, so every even processed twice (once by the manually created and configured callback handler and second time by another callback handler with default parameters).

The _wrap_configure verifies the existence of SentryLangchainCallback in args[2] which corresponds to local_callbacks parameter of the LangChain callback manager. But it ignores the callback provided as inheritable_callbacks where the assigned callback instance happens to be in the referenced code.

Having multiple callbacks sending errors to Sentry leads to more problems down the line.

Metadata

Metadata

Labels

Type

No type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions