Skip to content

[RUM] Extension WebGL fingerprinting RangeError reaches Error Tracking — the stack filter skips frames with no URL #1659

Description

@dawsontoth

Found in the daily RUM review for the 24h to 2026-08-27.

RangeError: Maximum call stack size exceeded is reaching Error Tracking with a stack that is nothing but recursive WebGLRenderingContext.getParameter frames:

RangeError: Maximum call stack size exceeded
  at WebGLRenderingContext.value [as getParameter] @ <anonymous>:4:28
  at WebGLRenderingContext.value [as getParameter] @ <anonymous>:7:56
  at WebGLRenderingContext.value [as getParameter] @ <anonymous>:7:56
  … (repeating)

Studio does not use WebGL. There is no getContext('webgl') anywhere in src/, and the only charting dependency (recharts) renders SVG. This is an anti-fingerprinting browser extension wrapping getParameter and recursing into its own wrapper — the user's extension failing, not Studio.

Why the existing filter misses it

shouldKeepEvent attributes errors by stack frame, which is the right design. But FRAME_URL (src/integrations/datadog/shouldKeepEvent.ts:47-49) only matches a frame when it ends in a real https://, blob:, or *-extension:// URL. These frames end in <anonymous>:4:28 — no URL at all — so every line is skipped by the if (!url) continue at shouldKeepEvent.ts:71-73. With no frame located, sawThirdPartyFrame stays false, originatesInThirdPartyScript returns false, and the event is kept as Studio's own.

This is the same gap class as #1645, one step further out. #1645 fixed frames whose URL used an unrecognised scheme; this is frames that carry no URL at all.

Volume

window events sessions
24h to 2026-08-27 6 3
each of the 6 preceding days 0 0
30d 28 14

3 of 116 sessions (2.6%) in the 24h window. source: console, handling: handled, view /. Episodic — it goes quiet for days, so a zero-day is not evidence it is gone.

Low volume today, but the per-session rate of an extension-driven family is structurally unbounded: #1645 was four sessions producing 1,486 events and 87% of all RUM errors. The reason to fix it is that it is a systematic hole in the attribution, not today's count.

The open design question

The naive fix — treat an all-unresolvable stack as third-party — is not obviously safe. Studio code can also produce a stack overflow, and a genuine recursion in our own code may well arrive with truncated or anonymous frames in some browsers, so a blanket rule risks dropping a real bug and would be silent about it.

Options, none of them free:

  1. Treat a stack with zero located frames as third-party. Simple; risks swallowing genuine Studio stack overflows.
  2. Match the recursion signature (a single frame repeating N times with no located URL). Narrow, but signature matching is what shouldKeepEvent.ts:153-154 deliberately argues against.
  3. Match on the Web API in the frame's function name (WebGLRenderingContext), since Studio provably never calls it. Precise here, but a per-API allowlist that grows one entry per extension.
  4. Leave it. It is 6 events; revisit if it grows.

Worth a decision rather than a default. Filing rather than fixing for that reason.

Verification notes

  • No WebGL in src/: grep -rniE "webgl|getContext\(" src returns only TanStack Table's cell.getContext().
  • Filter behavior traced in shouldKeepEvent.ts:66-82, not inferred.

Metadata

Metadata

Assignees

No one assigned

    Labels

    rumFrom real user monitoring where we aim to keep users happy

    Type

    Fields

    Priority

    P3

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions