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

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions