HarperFast / HarperFast/studio

[RUM] LinkedIn Insight Tag throws unhandled "window.lintrk is not a function" — our global insertBefore patch puts a first-party frame on every vendor tag's stack

Open
#1,696 0 comments 0 reactions 0 assignees View on GitHub
rum
Dominant language
TypeScript
Stars
5
Forks
4
Avg merge
1d 8h
Merged PRs (30d)
40

Description

`window.lintrk is not a function` reaches Error Tracking as an **unhandled** `TypeError`:
**24 events across 5 sessions in 30 days**, 12 of them from a single session in the last 24h. All on
the `/` entry point.

`lintrk` appears nowhere in this repo. It is the LinkedIn Insight Tag, injected by the GTM container
(`GTM-5QQX432`, loaded from `useGTM()` in `src/App.tsx`). GTM inserts an inline snippet that calls
`window.lintrk(...)`; when `snap.licdn.com/li.lms-analytics/insight.min.js` has not loaded — blocked
by an ad blocker, or just slower than the snippet — the call throws.

## Why `shouldKeepEvent` cannot drop it

The stack is:

```
TypeError: window.lintrk is not a function
at @ :1:8 <- GTM's inline script
at Node.insertBefore @ .../assets/index-D9wn3O9N.js:825:42836 <- OUR code
at @ https://www.googletagmanager.com/...
at CS @ https://www.googletagmanager.com/...
... (all remaining frames googletagmanager.com)
```

`originatesInThirdPartyScript` in `src/integrations/datadog/shouldKeepEvent.ts` returns `false` as
soon as one located frame is neither `static.reo.dev`, nor `*-extension://`, nor
`/assets/vendor-datadog-*.js`. The `Node.insertBefore` frame is ours: it is
`src/lib/installBrowserTranslationDomGuard.ts:52-53`, which patches `Node.prototype.insertBefore`
globally (the #1388 browser-translation fix). Confirmed by reading the deployed chunk at exactly that
offset:

```js
let r=Node.prototype.insertBefore;Node.prototype.insertBefore=function(e,t){
return t instanceof Node&&t.parentNode!==this?r.call(this,e,null):r.call(this,e,t)}
```

So the filter is working as written — but that global patch **puts a first-party frame on the stack of
every third-party script that inserts a DOM node**, and an inline `` executes synchronously
during insertion, so anything it throws propagates through our frame. This is broader than LinkedIn:
any vendor tag that throws while being injected is now attributed to Studio.

## Options

- Add `www.googletagmanager.com` (and `snap.licdn.com`) to `THIRD_PARTY_SCRIPT_FRAME`. Smallest change,
and consistent with the comment already on that constant.
- Or make `originatesInThirdPartyScript` treat the DOM-guard frame the way it treats
`INSTRUMENTATION_FRAME` — it is our code but it is never the *cause*, only a shim on the path. This
is the more general fix, and it would also cover the next vendor tag.

Volume is low, so this is hygiene rather than urgent: it costs one Error Tracking issue and a
bursty 12-events-per-session tail. Related third-party-attribution issues: #1645, #1659, #1620.
Related to #1684, which covers the cost of loading these tags eagerly in the first place.

Contributor guide

Open the contributing guide

Research direction

Start in src/integrations/datadog/shouldKeepEvent.ts and src/lib/installBrowserTranslationDomGuard.ts, tracing how the DOM-guard frame affects the existing third-party attribution check. Compare the two listed options and add coverage for a vendor-thrown error passing through the guard; done means that error is no longer attributed to Studio without regressing existing first-party filtering.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
observability-sre
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.