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
- 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
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