Skip to content

fix(OUT-3553): drop browser-extension noise from Sentry - #196

Open
priosshrsth wants to merge 3 commits into
mainfrom
fix/OUT-3553-origin-debug-instrumentation
Open

fix(OUT-3553): drop browser-extension noise from Sentry#196
priosshrsth wants to merge 3 commits into
mainfrom
fix/OUT-3553-origin-debug-instrumentation

Conversation

@priosshrsth

Copy link
Copy Markdown
Collaborator

Changes

  • Adds a denyUrls list in the client Sentry init for chrome-extension://, moz-extension://, and safari(-web)?-extension:// so any native exception whose top stack frame lives in extension-owned code is dropped.
  • Adds a beforeSend marker filter that drops events whose serialized message / exception / extra / recent breadcrumbs contain any of: multichainWallet, contentscriptFunctionCall, postMessageToContentScript, or the extension URL schemes. This catches extensions that inject content scripts into our page context and log errors via console (no stack frame to denyUrls on).

Root cause (OUT-3553)

The Sentry issue "Error: Origin not allowed" was being emitted from a visitor's crypto wallet browser extension. The Sentry event payload included:

{
  arguments: [ [postMessageToContentScript],
    { callFrom: inPage, funcName: getExtensionInfo,
      moduleName: multichainWallet, type: contentscriptFunctionCall, … } ],
  logger: console
}

This is the extension's own content script failing its own origin-allowlist check and logging via console.error. Because enableLogs: true is on in the client init, Sentry's console integration captures those logs and files them against our project. Nothing in our code triggers this, there is no user-facing impact, and there is no fix possible on the producer side (we don't control the extension).

Testing Criteria

  • Verify a synthetic extension-shaped console error is dropped. In a browser console on a preview build, run:
    console.error('Error: Origin not allowed', { arguments: [['postMessageToContentScript'], { moduleName: 'multichainWallet', type: 'contentscriptFunctionCall' }], logger: 'console' })
    and confirm the event does not appear in Sentry.
  • Verify an ordinary error still reports. throw new Error('sentry-smoke-test') in the console and confirm it does appear in Sentry with stack + replay.
  • Confirm OUT-3553 stops receiving new events after release.
  • Loom: pending

Notes

  • Filter is intentionally narrow (specific wallet-extension markers + extension URL schemes) so we do not accidentally swallow legitimate errors. If a different extension starts leaking, we extend EXTENSION_NOISE_MARKERS.
  • No server-side change required — extensions don't run server-side.

Impact & Surface Area of Change

  • Only src/instrumentation-client.ts is touched. Behavior change is limited to the client Sentry pipeline: two extra short-circuits before events are sent.
  • Other Sentry features untouched: replay integration, tracesSampleRate, enableLogs, sendDefaultPii are all preserved.
  • Watch for: unexpected drop in total Sentry event volume (expected, that's the point) — confirm by checking that non-extension issues are still being reported for a release window.

🤖 Generated with Claude Code

A multichainWallet crypto wallet extension was leaking "Origin not allowed"
errors into Sentry via console-log forwarding. The throw originates inside
the extension's content script (its own origin allowlist check) and has
nothing to do with our code.

Add two filters in the client Sentry init:
- `denyUrls` for chrome-/moz-/safari-extension:// so native exceptions
  originating in extension-owned code are dropped by stack frame.
- `beforeSend` marker check that catches extension content scripts logging
  via console in our page context (no stack frame to filter on).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@linear-code

linear-code Bot commented Apr 23, 2026

Copy link
Copy Markdown

@vercel

vercel Bot commented Apr 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
client-home-v3 Ready Ready Preview, Comment Apr 23, 2026 0:15am

Request Review

@greptile-apps

greptile-apps Bot commented Apr 23, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds two Sentry client-side filters to suppress browser-extension console errors from polluting the project's issue feed: a denyUrls list (covers stack-frame exceptions) and a beforeSend content scan against known wallet-extension string markers (covers console-injected events without stack frames).

  • P1 bug: event.breadcrumbs?.slice(-10) always throws TypeError because breadcrumbs is { values?: Breadcrumb[] }, not an array. The try/catch silently swallows it and returns false, so the breadcrumb leg of the probe is never evaluated. Fix: use event.breadcrumbs?.values?.slice(-10).
  • P2: EXTENSION_NOISE_MARKERS includes safari-web-extension:// but not safari-extension://, while the denyUrls regex covers both via safari(-web)?-extension://.

Confidence Score: 4/5

Safe to merge after fixing the breadcrumb .slice() bug; the primary filtering goal for OUT-3553 still works via the message/exception/extra probe.

One P1 defect: the breadcrumb path of isBrowserExtensionNoise always throws a TypeError (caught silently), making that leg of the filter non-functional. The specific OUT-3553 marker values appear in extra/message so the immediate fix still works, but the code doesn't match its stated intent and future breadcrumb-only extension noise would slip through.

src/instrumentation-client.ts — specifically line 28 (event.breadcrumbs?.sliceevent.breadcrumbs?.values?.slice)

Important Files Changed

Filename Overview
src/instrumentation-client.ts Adds denyUrls and beforeSend to filter browser-extension noise; the breadcrumb slice path silently throws because breadcrumbs is {values:[]} not an array, rendering that leg of the filter inoperative.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Sentry captures event] --> B{denyUrls match?\nTop stack frame in\nextension:// URL?}
    B -- Yes --> C[Drop event]
    B -- No --> D{beforeSend:\nisBrowserExtensionNoise?}
    D --> E[JSON.stringify probe\nmessage + exception\n+ extra + breadcrumbs]
    E --> F{breadcrumbs exists?}
    F -- No --> G[probe includes message/exception/extra only]
    F -- Yes --> H['.slice -10' throws TypeError\n→ catch returns false\n⚠️ breadcrumb path broken]
    G --> I{Any EXTENSION_NOISE_MARKERS\nin probe?}
    H --> I
    I -- Yes --> J[Return null → Drop event]
    I -- No --> K[Return event → Send to Sentry]
Loading

Reviews (1): Last reviewed commit: "fix(OUT-3553): drop browser-extension no..." | Re-trigger Greptile

Comment thread src/instrumentation-client.ts Outdated
message: event.message,
exception: event.exception,
extra: event.extra,
breadcrumbs: event.breadcrumbs?.slice(-10),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Breadcrumbs are an object, not an array — .slice() always throws

Sentry.ErrorEvent.breadcrumbs is typed as { values?: Breadcrumb[] } | undefined, not an array. Calling .slice(-10) on the wrapper object throws TypeError: event.breadcrumbs.slice is not a function, which the try/catch silently swallows, returning false. This means the breadcrumb path of the probe is always empty — any extension noise that only surfaces in breadcrumbs (e.g., a console.log breadcrumb containing multichainWallet) will not be filtered.

The fix is to access .values first:

Suggested change
breadcrumbs: event.breadcrumbs?.slice(-10),
breadcrumbs: event.breadcrumbs?.values?.slice(-10),

Comment thread src/instrumentation-client.ts Outdated
'postMessageToContentScript',
'chrome-extension://',
'moz-extension://',
'safari-web-extension://',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 safari-extension:// missing from string markers

The denyUrls regex uses safari(-web)?-extension://, which matches both safari-extension:// and safari-web-extension://. The EXTENSION_NOISE_MARKERS list only includes safari-web-extension://, leaving safari-extension:// uncovered for the isBrowserExtensionNoise content-scan path. For consistency, add the plain variant:

Suggested change
'safari-web-extension://',
'safari-web-extension://',
'safari-extension://',

`postMessageToContentScript` is a generic function name that could in
theory collide with legit console output. `contentscriptFunctionCall`
(the message `type` discriminator) and `multichainWallet` are specific
enough to stand on their own.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the secondary markers and the breadcrumb probe; `multichainWallet` in
the event payload is specific enough on its own, and `denyUrls` still
handles extension-originated native exceptions by stack frame.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants