fix(browser): Fix internal frame detection in minified bundles#20802
fix(browser): Fix internal frame detection in minified bundles#20802chargome wants to merge 2 commits into
Conversation
size-limit report 📦
|
| // When processEvent runs inside a sentryWrapped call, the outermost frame is always | ||
| // the sentryWrapped function. This works regardless of minification/bundling because | ||
| // it's a runtime check, not a source pattern match. | ||
| if (insideSentryWrapped) { | ||
| return true; | ||
| } |
There was a problem hiding this comment.
Bug: In non-minified builds, isSentryInternalFrame incorrectly flags user code as internal when _sentryWrappedDepth > 0, causing valid events from wrapped functions to be silently dropped.
Severity: HIGH
Suggested Fix
Remove the unconditional check in isSentryInternalFrame that treats the frame at index 0 as internal when insideSentryWrapped is true. The logic relies on the assumption that the sentryWrapped frame is always present, but it is stripped out in non-minified builds before this filter runs. The check should be removed to prevent misclassifying user code as internal.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/core/src/integrations/third-party-errors-filter.ts#L136-L141
Potential issue: In non-minified builds, the `isSentryInternalFrame` function
incorrectly assumes the first stack frame is always `sentryWrapped` when an error occurs
inside a wrapped function. However, a preceding function, `stripSentryFramesAndReverse`,
removes the `sentryWrapped` frame by its literal name. This causes the actual user code
frame to be misclassified as an internal Sentry frame and subsequently filtered out.
When all frames are filtered out, an `every()` check on the empty frame list becomes
vacuously true, causing the entire event to be silently dropped, even though it
originates from first-party code.
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.
Reviewed by Cursor Bugbot for commit 1ae6a53. Configure here.
| // it's a runtime check, not a source pattern match. | ||
| if (insideSentryWrapped) { | ||
| return true; | ||
| } |
There was a problem hiding this comment.
Chained errors cause wrong frame filtered as internal
Medium Severity
When insideSentryWrapped is true, isSentryInternalFrame unconditionally returns true for frameIndex === 0. However, getFramesFromEvent concatenates frames from all exception.values entries in order — for chained errors (with cause), values[0] is the root cause, so index 0 in the combined array is the outermost frame of the root cause, not the sentryWrapped frame. This causes a legitimate user/library frame to be incorrectly filtered as Sentry-internal, potentially leading to false error drops or incorrect third-party tagging.
Reviewed by Cursor Bugbot for commit 1ae6a53. Configure here.
| // it's a runtime check, not a source pattern match. | ||
| if (insideSentryWrapped) { | ||
| return true; | ||
| } |
There was a problem hiding this comment.
I think this might be a legit issue, maybe we can narrow it down with something like:
const maybeInsideSentryWrapped = insideSentryWrapped && event.exception?.values?.length === 1;and then gate it further to only the minified-shaped case:
function isLikelyMinifiedSentryWrappedFrame(frame: StackFrame): boolean {
return !frame.context_line && !frame.pre_context && !!frame.function && frame.function.length <= 2;
}WDYT?


The
ignoreSentryInternalFramesoption inthirdPartyErrorFilterIntegrationrelied on source-code-level signals (filename, context_line, comment patterns) that are all lost after minification.This PR adds a runtime depth counter (
GLOBAL_OBJ._sentryWrappedDepth) that tracks whether processEvent is running inside a sentryWrapped call. This works regardless of minification and also covers framework-caught errors (e.g. Vue swallowing the error before sentryWrapped'scatchfires).closes #20687