Summary
Breadcrumbs are silently dropped from EventLoopBlocked events sent by eventLoopBlockIntegration (from @sentry/node-native) because Scope.update() does not copy the breadcrumbs field from a plain scope-data object.
Reproduction
const Sentry = require('@sentry/node');
const { eventLoopBlockIntegration } = require('@sentry/node-native');
Sentry.init({
dsn: '__YOUR_DSN__',
integrations: [eventLoopBlockIntegration({ threshold: 1000 })],
});
Sentry.addBreadcrumb({ category: 'test', message: 'breadcrumb before block', level: 'info' });
// 1. Sanity check: a normal event DOES include the breadcrumb
Sentry.captureException(new Error('normal event'));
// 2. Block the event loop past the threshold to trigger an EventLoopBlocked event
setTimeout(() => {
const end = Date.now() + 3000;
while (Date.now() < end) { /* busy loop */ }
}, 2000);
Root cause
In the watchdog worker (packages/node-native/src/event-loop-block-watchdog.ts), the scope is reconstructed like this:
const scope = crashedThread.pollState?.scope
? new Scope().update(crashedThread.pollState.scope).getScopeData()
: new Scope().getScopeData();
applyScopeToEvent(event, scope);
Scope.update() in @sentry/core only copies tags, attributes, extra, user, contexts, level, fingerprint, propagationContext, and conversationId — it never reads breadcrumbs or attachments. The fresh Scope retains its empty _breadcrumbs, so applyScopeToEvent overwrites the event's breadcrumbs with undefined.
The same round-trip also drops attachments.
Suggested fix
The safest targeted fix is to carry breadcrumbs (and attachments) over explicitly after reconstructing the scope in event-loop-block-watchdog.ts, similar to what the old anrIntegration worker did:
const scope = crashedThread.pollState?.scope
? new Scope().update(crashedThread.pollState.scope).getScopeData()
: new Scope().getScopeData();
scope.breadcrumbs = crashedThread.pollState?.scope?.breadcrumbs ?? [];
Environment
@sentry/electron: 7.15.0
@sentry/node-native: 10.62.0
@sentry/core: 10.62.0
- Electron: 40
Summary
Breadcrumbs are silently dropped from
EventLoopBlockedevents sent byeventLoopBlockIntegration(from@sentry/node-native) becauseScope.update()does not copy thebreadcrumbsfield from a plain scope-data object.Reproduction
Root cause
In the watchdog worker (
packages/node-native/src/event-loop-block-watchdog.ts), the scope is reconstructed like this:Scope.update()in@sentry/coreonly copiestags,attributes,extra,user,contexts,level,fingerprint,propagationContext, andconversationId— it never readsbreadcrumbsorattachments. The freshScoperetains its empty_breadcrumbs, soapplyScopeToEventoverwrites the event's breadcrumbs withundefined.The same round-trip also drops
attachments.Suggested fix
The safest targeted fix is to carry breadcrumbs (and attachments) over explicitly after reconstructing the scope in
event-loop-block-watchdog.ts, similar to what the oldanrIntegrationworker did:Environment
@sentry/electron: 7.15.0@sentry/node-native: 10.62.0@sentry/core: 10.62.0