You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
gql: execute() leaves its event processor on the isolation scope, so later unrelated errors are reported as GraphQL requests #8262
gql is a client, so it's often called outside a per-request isolation scope (scripts, workers, task loops), or many times inside one request. The processors outlive the query and apply to every later event on that scope.
importsentry_sdkfromgqlimportClient, gqlfromgql.transport.requestsimportRequestsHTTPTransportfromsentry_sdk.integrations.gqlimportGQLIntegrationsentry_sdk.init(dsn=..., integrations=[GQLIntegration()], send_default_pii=True)
client=Client(transport=RequestsHTTPTransport(url="http://example.com/graphql"))
foriinrange(100):
client.execute(gql("query Q%d { example }"%i)) # all succeed# later, unrelated to GraphQLtry:
raiseValueError("unrelated error")
exceptValueError:
sentry_sdk.capture_exception()
Other processors on the scope get wiped. Once a scope has more than 20 processors, Scope.add_event_processor clears all of them. So 21 gql calls in one request remove processors added by the app or other integrations. In the repro, a processor added to the same isolation scope before 21 queries is gone afterwards, and the next error event is missing its tag.
contexts.response.type is a self-reference. Both branches of the processor do response.update({"data": ..., "type": response}), which sets type to the dict itself, so it's serialized as "<cyclic>":
Possible fix: fork a scope around real_execute (with sentry_sdk.new_scope() as scope:) and add the processor there, so it only applies to events captured during the query (including the TransportQueryError event), and set "type": "response". Happy to open a PR with tests.
Activity
linear-code commentedon Nov 12, 2026
PY-3075