Conversation
Demonstrates breadcrumb leaking between NestJS requests due to missing request isolation scope. Breadcrumbs from earlier requests appear on later error events. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add SentryGlobalFilter as APP_FILTER provider - Throw Error instead of manually calling captureException() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrote reproduction to demonstrate the actual root cause: background jobs (cron/graphile-worker/BullMQ) run outside HTTP request context and pollute the default isolation scope. When httpServerIntegration clones this scope for new requests, it inherits stale breadcrumbs. Added test-repro.sh for one-command reproduction. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add breadcrumb leaking reproductions for: - @nestjs/schedule (@interval) - always active - @nestjs/event-emitter (@onevent) - always active - @nestjs/bullmq (@processor) - requires REDIS_URL - nestjs-graphile-worker (@task) - requires DATABASE_URL Both schedule and event-emitter confirmed leaking breadcrumbs into HTTP request error events. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The graphile-worker runner wasn't being started, so tasks were queued but never processed. Now all 4 frameworks confirmed leaking: schedule-job, event-job, bullmq-job, graphile-job. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||
| const { BullModule } = require("@nestjs/bullmq"); | ||
| imports.push( | ||
| BullModule.forRoot({ connection: { url: process.env.REDIS_URL } }) |
There was a problem hiding this comment.
BullMQ connection silently ignores invalid url property
Medium Severity
The BullModule.forRoot({ connection: { url: process.env.REDIS_URL } }) call passes a url property in the connection options, but ioredis's RedisOptions does not support a url property (the feature request was explicitly rejected in ioredis#871). The url field is silently ignored, and ioredis defaults to localhost:6379. This means the BullMQ test case only works by coincidence when Redis happens to be on localhost, and will silently connect to the wrong server for any other REDIS_URL value. The connection URL needs to be parsed into host/port/password fields or an ioredis instance created from the URL string.


Summary
Reproduces sentry-javascript#17742 — breadcrumbs from NestJS background jobs leak into HTTP request error events.
Background jobs run outside the HTTP request context, so they add breadcrumbs to the default isolation scope. When a new HTTP request arrives,
httpServerIntegrationclones the default scope viagetIsolationScope().clone()— inheriting all stale breadcrumbs from background jobs.Background Job Frameworks Covered
@nestjs/schedule@Interval@nestjs/event-emitter@OnEvent@nestjs/bullmq@ProcessorREDIS_URLnestjs-graphile-worker@TaskDATABASE_URLRoot Cause
In
packages/node-core/src/integrations/http/httpServerIntegration.ts:185:This clones the default isolation scope, which has been polluted by background job breadcrumbs.
How to Run
Optionally set
REDIS_URL=redis://localhost:6379and/orDATABASE_URL=postgres://user:pass@localhost:5432/dbnameto also test BullMQ and Graphile Worker leaking.Expected Output
Actual Output (all 4 frameworks enabled)
Setup Details
SentryModule.forRoot(),SentryGlobalFilterasAPP_FILTERcaptureException)🤖 Generated with Claude Code