fix(replay): surface why a trigger-gated session is stuck buffering (#4453)
* fix(replay): surface why a trigger-gated session is stuck buffering
A URL trigger anchored to one exact URL combined with the default AND
trigger matching leaves a session in TRIGGER_PENDING forever: nothing
records, and the SDK emits no warning, so the failure is invisible from
the outside.
- Warn at config time when a URL trigger regex is anchored at both ends
with no wildcard/quantifier/alternation, so it can only ever match one
exact URL (e.g. `^https://app.example.com/$`).
- Name the pending trigger condition in the buffering diagnostic
("buffering: URL condition not matched") so a customer can tell which
leg failed instead of only seeing an unexplained "buffering".
- Treat a persisted recording config with no cache_timestamp as stale so
it is revalidated rather than trusted indefinitely.
Generated-By: PostHog Code
Task-Id: 5356ddcc-24d5-4a6d-86a6-833536ad327e
* fix(replay): reset buffering diagnostic once the session goes active
_maybeLogBufferingReason was only called from the buffering early-return
branch of _flushBuffer, so an active flush never cleared
_lastLoggedBufferingReason. After BUFFERING -> ACTIVE -> session rotation
-> BUFFERING for the same condition, the equality check suppressed the
diagnostic for the rest of the page lifetime.
Move the call above the branch so it runs on every flush: the method
already clears the saved reason when status is not BUFFERING, so a later
session that buffers for the same condition logs again. Diagnostic-only;
capture behaviour is unchanged, and because the method returns early when
not BUFFERING it does not add any trigger-status evaluations.
Generated-By: PostHog Desktop
Task-Id: bdb44927-92de-46fa-9812-db67396dbcd4
* fix(replay): make the buffering diagnostic read trigger status without side effects
_describePendingTriggerConditions polled each matcher's triggerStatus()
on every buffering flush (every RECORDING_BUFFER_TIMEOUT), and each of the
three matcher triggerStatus() methods writes a debug session property via
register_for_session. Because _persistSessionRegisteredPropKeys writes the
prop-keys array to sessionStorage unconditionally (no dirty check), a
session stuck buffering paid three extra synchronous sessionStorage writes
per flush indefinitely, purely to compute a debug-only message.
Add triggerStatusNoSideEffects() to the URL, event, and linked-flag
matchers (reusing the existing pure _urlTriggerStatus/_eventTriggerStatus
helpers) and have the diagnostic call it instead of triggerStatus(). The
side-effecting triggerStatus() used by the status getter is unchanged, so
the debug session properties are still written on the normal status path.
Generated-By: PostHog Desktop
Task-Id: bdb44927-92de-46fa-9812-db67396dbcd4
* fix(replay): address trigger diagnostic review
* refactor(replay): remove URL trigger regex heuristic
* fix(replay): address trigger diagnostics feedback
* fix(replay): classify pending trigger diagnostics
---------
Co-authored-by: posthog[bot] <206114724+posthog[bot]@users.noreply.github.com>
Co-authored-by: Manoel Aranda Neto <marandaneto@gmail.com> P
posthog[bot] committed
325870a3b6473b1dd302fa66b9a98a02287eb825
Parent: 6fcd055
Committed by GitHub <noreply@github.com>
on 8/22/2026, 6:44:07 AM