Developer Tooling
Error Tracking
Session Replay

When Error Logs Lie: Reproducing Production Failures with Session Replay

A stack trace tells you where the code threw. It rarely tells you what the user did in the thirty seconds before. Linking grouped frontend errors to session replay closes that gap—turning “cannot reproduce” into a concrete sequence of clicks, navigation, and API calls you can replay and fix.

TL;DR

Open a grouped error in your tracker, filter to replays from affected sessions, scrub backward from the exception, and compare failing vs healthy paths. Use replay for user context; keep error tracking for aggregation and release attribution. Do not treat either tool as a substitute for the other.

10 min read

LogNroll Team

Developer Tooling

The gap between a stack trace and a fix

Frontend error tracking is good at volume: fingerprinting exceptions, alerting on spikes, and tying crashes to a release or browser. What it is bad at is narrative. When Sentry or a similar tool shows Cannot read properties of undefined (reading 'id') with forty-seven occurrences this week, you know something is wrong. You do not know which user action left the object undefined.

Session replay records that narrative—DOM updates, route changes, network calls, and console output synchronized to a timeline. When you link an error event to the replay from the same session, you stop guessing and start watching. That pairing is the most reliable way we have found to reproduce production-only frontend bugs without asking users to screen-share or paste HAR files.

Error logs are not lying on purpose

They are optimized for aggregation, not storytelling. A minified stack trace from Chrome 124 on Android is accurate—it just omits the back-button navigation and the 403 on a prefetch that left your cache in a bad state. Replay supplies the omitted chapters.

Four reasons grouped errors mislead

Grouped errors hide individual paths

Error trackers collapse thousands of events into one fingerprint: same message, same top frame. That grouping is useful for triage but erases the navigation, form state, and API sequence that made one session fail and another succeed.

Stack traces lack user intent

A TypeError at line 142 tells you what broke, not why the user was there. Did they arrive via a marketing deep link? Skip onboarding? Open two tabs and submit the same form twice? None of that appears in the exception payload.

Local repro assumes clean state

Developers reproduce with fresh cookies, latest build, and predictable click paths. Production failures often involve stale localStorage, feature flags from a partial rollout, or a race between async calls that your test suite never simulates.

Third-party scripts change the story

Ad blockers, browser extensions, and tag managers inject timing and DOM side effects. An error that fires in 2% of sessions may correlate with a specific browser, locale, or script load order—context your error dashboard does not surface by default.

What to wire together at capture time

The workflow below only works if error events and replay share a session identifier. Before you debug your first linked replay, confirm your SDK setup passes the same session or replay ID into both pipelines:

SignalError trackerSession replay
Session IDTags every exception in the groupIndexes the recording for one visit
Release / buildAttributes spike to a deployFilters replays to the same artifact
User ID (hashed)Connects repeat failures across daysFinds prior sessions with similar paths
Custom breadcrumbsRoute changes, button clicks before throwVisible on the replay timeline as markers
Network + consoleAttached as event context when configuredFull synchronized timeline in the player

Sampling matters

If you capture 100% of errors but only 5% of sessions as replay, most crashes will have no video. Align sampling strategy with severity: always record replay when an unhandled exception fires, or when a custom fatal_ui_error event is emitted. Error-only replay capture costs less than full-session recording and preserves the sessions that matter for debugging.

A practical debugging workflow

1.Start from the error group, not a random session

Open the grouped issue in your error tracker. Note release version, browser breakdown, and first-seen date. Filter replays to sessions where the same error fired—or to users who hit the same route within the same release window.

2.Scrub backward from the crash

Jump to the exception timestamp, then rewind 30–60 seconds. Watch navigation, clicks, and network activity leading up to the throw. The bug is often in the step before the stack trace, not at the line that logged it.

3.Compare a failing session to a healthy one

When only some users hit the error, diff two replays on the same flow. Look for missing API responses, different query params, or UI states (disabled fields, hidden steps) that explain why one path threw and another did not.

4.Attach replay context to the fix

Link the replay URL in the ticket. Note user actions, request IDs, and console output alongside the stack trace. Reviewers and QA can validate the fix against real behavior instead of a one-line error message.

Example: undefined property after checkout redirect

Your error group shows TypeError: Cannot read properties of undefined (reading 'orderId') on the order confirmation page. The stack points to a selector that reads order data from client state. Locally, checkout always works—you land on confirmation with a populated store.

In replay, you filter sessions where the error fired and scrub backward. The user completed payment, received a 302 to /orders/confirm, then immediately hit the browser back button before the confirmation API returned. The page rendered with an empty order slice; the selector threw. No server log showed a failure—the API was still in flight. The stack trace was truthful about the line; replay was necessary to explain the navigation that caused it.

Stack trace vs replay: who owns what

Error tracking owns

  • Grouping and deduplication across users
  • Release regression detection and alerting
  • Source maps and symbolicated frames
  • Ownership routing and issue lifecycle

Session replay owns

  • Click and scroll sequence before the throw
  • Route transitions and timing between them
  • Network failures and slow responses in context
  • Visual proof for QA and product stakeholders

Tying into product analytics

Error spikes are product signals, not only engineering tickets. When a funnel step loses users the same hour an error group grows, replay lets you verify whether the drop is a UX bug, a performance issue, or unrelated traffic change:

Instrument errors as analytics events

Emit frontend_error with error fingerprint, route, and feature name. Compare event volume to funnel completion in the same dashboard slice.

Segment replays by cohort

Filter by plan tier, locale, or experiment variant when an error only affects a subset. Grouped counts alone will not show that enterprise SSO users skip a step free users never see.

Close the loop after deploy

Watch one replay from the fixed release on the same flow. Confirm the user path that previously threw now completes—before you mark the error group resolved.

For API failures that accompany frontend throws, see network debugging with session replay. For architecture details on how replay capture works alongside error pipelines, see our session replay architecture guide.

Common mistakes

Fixing from the top stack frame only

The throw site is often a symptom. Replay frequently shows the root cause is stale state, a missing API response, or a race two steps earlier.

Closing issues without watching a replay

If no replay exists for the error group, fix the sampling gap first. Resolving from stack traces alone tends to reproduce the same fingerprint in the next release.

Recording sensitive fields in replay

Error context and replay must both redact PII and secrets. A linked replay you cannot share with the team is as useless as an error log with masked everything.

Where LogNroll fits

LogNroll combines session replay with error and event timelines in one player. Group frontend exceptions by fingerprint, open the replay from the same session, and scrub through clicks, navigation, network calls, and console output aligned to the moment the error fired.

That workflow is built for the bugs error trackers surface but cannot explain: state left inconsistent after navigation, third-party script timing, and flows that only break on mobile or slow networks. Keep your existing error aggregator for grouping and alerts; use replay to answer the question every stack trace leaves open—what did the user do right before this broke?

Checklist: error tracking + session replay

  • Share session IDs between error capture and replay SDKs.
  • Sample replay at 100% when an unhandled exception fires.
  • Scrub backward from the error timestamp before reading the stack.
  • Compare failing and healthy replays on the same user flow.
  • Attach replay links to tickets so QA validates against real behavior.

Conclusion

Error logs are indispensable for knowing something failed in production. They are insufficient for learning how to reproduce it. Linking grouped frontend errors to session replay gives engineers the user context stack traces omit—clicks, routes, API timing, and UI state in the seconds before the crash. Wire the identifiers at capture time, scrub backward from the exception, and treat replay as the narrative layer your error tracker was never designed to store. That is how “cannot reproduce” becomes a closed ticket with evidence.