The posthog-js library is throwing error, when user is iddle
Bug description
Our Sentry reported over 170 errors during the last month, with this error thrown:
SecurityError: Failed to read a named property 'removeEventListener' from 'Window': Blocked a frame with origin "https://app.tradespace.io" from accessing a cross-origin frame.
at h (../../../node_modules/.pnpm/@[email protected]_patch_hash=4a974d451d029e3ef6c302f641dfaf41fb0881146b6d5198ccdbe8d50776b64f/node_modules/@rrweb/record/dist/record.js:3615:1)
at forEach (../../../node_modules/.pnpm/@[email protected]_patch_hash=4a974d451d029e3ef6c302f641dfaf41fb0881146b6d5198ccdbe8d50776b64f/node_modules/@rrweb/record/dist/record.js:5571:27)
at Array.forEach (<anonymous>)
at call (../../../node_modules/.pnpm/@[email protected]_patch_hash=4a974d451d029e3ef6c302f641dfaf41fb0881146b6d5198ccdbe8d50776b64f/node_modules/@rrweb/record/dist/record.js:5571:14)
at LazyLoadedSessionRecording.stop (../src/extensions/replay/external/lazy-loaded-session-recorder.ts:791:9)
at this._onSessionIdleResetForcedListener (../src/extensions/replay/external/lazy-loaded-session-recorder.ts:704:22)
at SimpleEventEmitter.emit (../../../node_modules/posthog-js/src/utils/simple-event-emitter.ts:21:13)
at this._enforceIdleTimeout (../../../node_modules/posthog-js/src/sessionid.ts:329:36)
at sentryWrapped (../../../node_modules/@sentry/browser/src/helpers.ts:117:17)
Please describe.
How to reproduce
- The users were idle for a long period of time
Related sub-libraries
- [ ] All of them
- [x] posthog-js (web)
- [ ] posthog-js-lite (web lite)
- [ ] posthog-node
- [ ] posthog-react-native
- [ ] @posthog/react
- [ ] @posthog/ai
- [ ] @posthog/nextjs-config
Additional context
The bug seems to happen to me, originating in the @rrweb/[email protected] / using the @rrweb/[email protected] in Posthog.
Updating to @rrweb/[email protected] may help.
Any advice, how can this be fixed in our repository?
I noticed, we still use PostHogProvider from posthog-js/react. Is this package deprecated? Should we use @posthog/react?
@PostHog/team-replay probably a replay issue since i see 'rrweb' logs
hey @lukasbicus can you share a little more about how you're using posthog replay - since there's an iframe cross origin issue here... this is our tidy-up code running, i guess there's an assumption about the context it's running in that isn't true for your setup
I noticed, we still use PostHogProvider from posthog-js/react. Is this package deprecated? Should we use @posthog/react?
i don't think that will help here, but yep you should move over at some point - although posthog-js/react is just a passthrough to @posthog/react so it won't change anything except tidiness
Hi @pauldambra - thanks for taking a look.
Here is what I found when I investigated the setup on our project:
// We init PostHog like this:
posthog.init(process.env.POST_HOG_API_KEY, {
api_host: process.env.POST_HOG_HOST,
defaults: '2025-05-24',
disable_session_recording: currentUser?.tradespaceEmployee ? true : false,
session_recording: {
recordCrossOriginIframes: false
}
});
if (currentUser) {
posthog.identify(currentUser.uuid, {
email: currentUser.email,
name: currentUser.fullName,
account_id: currentAccount.id,
account_user_id: currentAccountUser.id
});
}
import posthog from 'posthog-js';
// We wrap the app in the PostHogProvider:
// ...
<PostHogProvider client={posthog}>
{
//... the app itself.
}
</PostHogProvider>
We also use some feature flags on our project (useFeatureFlagEnabled from posthog-js/react).
Is this helpful? I'm not quite sure, how to answer this question. I watch videos of users' behavior only on Sentry.
Does your application run in an iframe?
When a user is idle for a long time and posthog recording is running we shut down the recorder to save resources and the error message looks like for some reason we can create the event listeners but when we are tearing down we get an error removing them 🫠
No, our application doesn't run in an iframe.
Hmmm, surprising the error has Blocked a frame with origin "https://app.tradespace.io/" from accessing a cross-origin frame.
something is in a frame 🙈
Hmmm, surprising the error has
Blocked a frame with origin "https://app.tradespace.io/" from accessing a cross-origin frame.something is in a frame 🙈
Ouu, that can be a clue. Our app runs on https://app.tradespacestaging.io/ or https://app.tradespace.io/. Usually, people use it from the browser. If it is used in an iframe, it has to be a very specific kind of usage. I'll discuss with my team and let you know with further findings.
awesome, thank you! very happy to ship a fix here but don't know what it would be 🙈 😅
Hi @pauldambra - We get your point. Of course, this package can't resolve our CORS issues.
Right now, we don't understand where the root of the issue is, as we don't use our app in an iframe 99 percent of the time, and the error happens on pages distant from this iframe. We will watch this issue further. Thanks for your insights.
No worries, thanks for you patience with the back-and-forth here
Do let us know how it goes, since even if it's not something we could fix (and ofc it might still be) we might be able to output a nicer error that makes this easier for the future traveller!
I was also able to reproduce this one on my local, by just idling for a longer period of time ~30 mins on the screen where the posthog is called. No iframe here as well
record.js:3615 Uncaught SecurityError: Failed to read a named property 'removeEventListener' from 'Window': Blocked a frame with origin "https://localhost.test" from accessing a cross-origin frame. at Ie.stop (lazy-loaded-session-recorder.ts:876:9) at lazy-loaded-session-recorder.ts:753:22 at Cn.emit (simple-event-emitter.ts:21:13) at sessionid.ts:330:36
using the php sdk, probably after reply inactivity it tries to do a cleanup?
Seems to fail on this._stopRrweb?.()
👋 hey @filipgymdesk the php sdk doesn't use rrweb at all, this could only come from the posthog-js SDK
SecurityError: Failed to read a named property 'removeEventListener' from 'Window': Blocked a frame with origin "localhost.test" from accessing a cross-origin frame.
this error is specifically referencing a frame.
do you run a CSP on your site?
the only thing I can think is that the rrweb SDK is trying to get a vanilla removeEventListener from an iframe (a very common technique) and that your CSP is blocking that
it's definitely not a general problem with all instances of stopping on idle so it's hard to investigate without more detail
My bad, it's JS indeed
public function posthog(): string {
$script = '<script>'
. '!function(t,e){var o,n,p,r;e.__SV||(window.posthog && window.posthog.__loaded)||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init Ce Ds js Te Os As capture Ye calculateEventProperties Us register register_once register_for_session unregister unregister_for_session Hs getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSurveysLoaded onSessionId getSurveys getActiveMatchingSurveys renderSurvey displaySurvey canRenderSurvey canRenderSurveyAsync identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty qs Ns createPersonProfile Bs Cs Ws opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing get_explicit_consent_status is_capturing clear_opt_in_out_capturing Ls debug L zs getPageViewId captureTraceFeedback captureTraceMetric".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);'
. "posthog.init('phc_.......', {"
. "api_host: 'https://us.i.posthog.com',"
. "defaults: '2025-05-24',"
. "person_profiles: 'always',"
. "})";
if (Users::isLogged() && !isset($this -> view -> skipPosthogIdentify)) {
$script .= "
posthog.identify(
'" . Users::getId() . "',
{ email: '" . Users::getIdentity() -> email . "', name: '" . Users::getIdentity() -> name . "' },
);";
}
$script .= "</script>";
return $script;
}
I'm getting this error
SecurityError: Failed to read a named property 'removeEventListener' from 'Window': An attempt was made to break through the security policy of the user agent.
Found the culprit call to be this from Sentry error stack:
posthog.stopSessionRecording();
My site uses CSP.
hey @pkpio could you share the CSP?
we do remove event listeners when people call stop, but they're event listeners we added suggesting we had permission to add event listeners but not remove them 🤯
This is our CSP for the auth pages where we do this call - it's more relaxed than all our other pages
"default-src * 'unsafe-inline' 'unsafe-eval' data: blob:; script-src * 'unsafe-inline' 'unsafe-eval'; connect-src * 'unsafe-inline'; img-src * data: blob: 'unsafe-inline'; frame-src *; style-src * 'unsafe-inline';"
We are seeing something similar; in our case, we're mostly following the recommended policy, though I will try adding worker-src