From 53e6de3a9b993d82226bf030da00d58bb7b655c2 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 7 Apr 2026 17:33:23 +0200 Subject: [PATCH 1/2] fix(core): Only attach `flags` context to error events --- packages/core/src/utils/featureFlags.ts | 6 ++ .../core/test/lib/utils/featureFlags.test.ts | 59 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/packages/core/src/utils/featureFlags.ts b/packages/core/src/utils/featureFlags.ts index 4fa3cdc5ac8d..c7551c379d3c 100644 --- a/packages/core/src/utils/featureFlags.ts +++ b/packages/core/src/utils/featureFlags.ts @@ -28,6 +28,12 @@ const SPAN_FLAG_ATTRIBUTE_PREFIX = 'flag.evaluation.'; * Copies feature flags that are in current scope context to the event context */ export function _INTERNAL_copyFlagsFromScopeToEvent(event: Event): Event { + if (event.type) { + // No need to add the flags context to transaction events. + // Spans already get the flag.evaluation attributes. + return event; + } + const scope = getCurrentScope(); const flagContext = scope.getScopeData().contexts.flags; const flagBuffer = flagContext ? flagContext.values : []; diff --git a/packages/core/test/lib/utils/featureFlags.test.ts b/packages/core/test/lib/utils/featureFlags.test.ts index 7813452ad419..9fd4884787e6 100644 --- a/packages/core/test/lib/utils/featureFlags.test.ts +++ b/packages/core/test/lib/utils/featureFlags.test.ts @@ -2,11 +2,15 @@ import { afterEach, describe, expect, it, vi } from 'vitest'; import { getCurrentScope } from '../../../src/currentScopes'; import { debug } from '../../../src/utils/debug-logger'; import { + _INTERNAL_copyFlagsFromScopeToEvent, _INTERNAL_insertFlagToScope, _INTERNAL_insertToFlagBuffer, type FeatureFlag, } from '../../../src/utils/featureFlags'; +import * as currentScopeModule from '../../../src/currentScopes'; +import type { Event } from '../../../src/types-hoist/event'; + describe('flags', () => { describe('insertFlagToScope()', () => { it('adds flags to the current scope context', () => { @@ -109,4 +113,59 @@ describe('flags', () => { ]); }); }); + + describe('copyFlagsFromScopeToEvent()', () => { + it.each(['transaction', 'replay_event', 'feedback', 'profile'])('does not add flags context to %s events', type => { + vi.spyOn(currentScopeModule, 'getCurrentScope').mockReturnValue({ + // @ts-expect-error - only returning partial scope data + getScopeData: () => ({ + contexts: { + flags: { values: [{ flag: 'feat1', result: true }] }, + }, + }), + }); + + const event = { + type: type, + spans: [], + } as Event; + + const result = _INTERNAL_copyFlagsFromScopeToEvent(event); + + expect(result).toEqual(event); + expect(getCurrentScope).not.toHaveBeenCalled(); + }); + + it('adds add flags context to error events', () => { + vi.spyOn(currentScopeModule, 'getCurrentScope').mockReturnValue({ + // @ts-expect-error - only returning partial scope data + getScopeData: () => ({ + contexts: { + flags: { + values: [ + { flag: 'feat1', result: true }, + { flag: 'feat2', result: false }, + ], + }, + }, + }), + }); + + const event: Event = { + exception: { + values: [ + { + type: 'Error', + value: 'error message', + }, + ], + }, + }; + + const result = _INTERNAL_copyFlagsFromScopeToEvent(event); + + expect(result).toEqual(event); + expect(getCurrentScope).toHaveBeenCalled(); + }); + }); }); From c716d4d5f33e689bd12bb4dbd83539a5cb5cbc8c Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Wed, 8 Apr 2026 12:50:03 +0200 Subject: [PATCH 2/2] better test assertion --- .../core/test/lib/utils/featureFlags.test.ts | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/core/test/lib/utils/featureFlags.test.ts b/packages/core/test/lib/utils/featureFlags.test.ts index 9fd4884787e6..534285b4f9f4 100644 --- a/packages/core/test/lib/utils/featureFlags.test.ts +++ b/packages/core/test/lib/utils/featureFlags.test.ts @@ -164,7 +164,30 @@ describe('flags', () => { const result = _INTERNAL_copyFlagsFromScopeToEvent(event); - expect(result).toEqual(event); + expect(result).toEqual({ + contexts: { + flags: { + values: [ + { + flag: 'feat1', + result: true, + }, + { + flag: 'feat2', + result: false, + }, + ], + }, + }, + exception: { + values: [ + { + type: 'Error', + value: 'error message', + }, + ], + }, + }); expect(getCurrentScope).toHaveBeenCalled(); }); });