
How do I debug a frontend JavaScript error that only happens for some users/browsers and not locally?
Quick Answer: This is the classic “works on my machine” frontend bug: it only shows up in certain browsers, devices, or network conditions. To debug it, you need production-side visibility—errors, stack traces, and user context—from real user sessions, not just your local dev tools.
The Quick Overview
- What It Is: A practical way to capture, inspect, and fix frontend JavaScript errors that only appear for some users or browsers in production using Sentry’s monitoring features.
- Who It Is For: Frontend and full‑stack engineers who are tired of guessing why a bug happens “out there” but never locally.
- Core Problem Solved: Connecting “some users see a weird JS error” to the exact code path, browser, release, and deploy that caused it—so you can reproduce and fix it quickly.
How It Works
When a frontend JavaScript error only happens for some users/browsers and not locally, the missing piece is usually context. You don’t know:
- Which browser or OS they’re on
- Which release was deployed
- What code actually threw (especially if it’s minified)
- What the user did right before it failed
Sentry plugs into your frontend via an SDK. It listens for errors and performance data in the user’s browser, then sends that as events to Sentry.io—non‑blocking and asynchronously—where they’re grouped into issues with stack traces, environment details, release info, and optional Session Replay. That lets you walk through the exact user experience that led to the bug.
From there you:
- Instrument your app: Add the Sentry JavaScript SDK, connect your release and sourcemaps, and enable tracing/Session Replay if you want deeper context.
- Capture and inspect the error: Let Sentry collect real‑world errors from affected browsers and environments, then drill into stack traces, tags, and user actions to understand the root cause.
- Fix and verify: Use Ownership Rules and Suspect Commits to route issues to the right developer, ship a fix, and confirm in Sentry that the error volume drops for those specific browsers/users.
Features & Benefits Breakdown
| Core Feature | What It Does | Primary Benefit |
|---|---|---|
| Error Monitoring | Captures frontend JavaScript exceptions with stack traces, browser/OS, environment, and release data. | See exactly where and when the error happens in production—even when you can’t reproduce it locally. |
| Session Replay | Records pixel‑perfect user sessions tied to error events (clicks, navigation, console logs). | Watch what the user did before the error instead of guessing from a bug report. |
| Tracing & Performance | Captures transactions and spans across frontend and backend services. | Correlate a flaky frontend error with slow APIs, failed requests, or layout shifts. |
Ideal Use Cases
- Best for hard‑to‑reproduce, user‑specific bugs: Because Sentry collects real production data per user session (browser, environment, release, stack trace, replay), you stop trying to guess the exact combination of factors that triggered the error.
- Best for browser‑specific or feature‑flagged issues: Because you can slice issues by browser, OS, feature flag, or release, and see if the error only impacts Safari, a specific mobile OS, or a new cohort.
Limitations & Considerations
- You still need to deploy the SDK: Sentry can’t help with historical bugs that occurred before instrumentation. Add the SDK early—ideally in every environment, including staging.
- Not every session needs full replay: Session Replay gives incredible context but generates additional telemetry. Use it selectively (for key flows, specific releases, or certain environments) to balance cost and visibility.
Pricing & Plans
Sentry is usage‑based. You send telemetry—errors, transactions (spans), Session Replays, logs, profiling data—within quotas you control, and you can add pay‑as‑you‑go budget for overages. You also get a fixed number of dashboards per plan (10 on Developer, 20 on Team, unlimited on Business+).
- Developer Plan: Best for small teams or individual developers needing solid error monitoring and tracing to find and fix tricky frontend issues.
- Team / Business+ Plans: Best for growing or enterprise teams needing higher volumes, more dashboards, governance (SAML + SCIM on Business+), advanced workflow, and options like a technical account manager on Enterprise.
Below is how I typically walk a team through debugging a “some users only” frontend JavaScript error with Sentry end‑to‑end.
1. Understand Why It Only Happens for Some Users/Browsers
When a bug doesn’t show up locally but shows up in production:
- Browser differences: Safari vs Chrome vs Firefox; different JS engines, DOM quirks, feature support.
- OS/Device differences: iOS vs Android vs desktop; screen size, input types, touch vs mouse, GPU.
- Network conditions: Slow 3G vs fast Wi‑Fi; timeouts, partial loads, race conditions.
- Release drift: You’re testing on main or staging, but users are on an older or different deployed release.
- Feature flags/config: Users in certain cohorts or regions see different code paths.
Reproducing all of these combinations locally is painful. Instead, you need:
- A way to capture errors in the actual environment
- Metadata about browser, OS, and release
- The exact stack trace with sourcemaps
- Optionally, a visual replay of the user’s session
That’s the gap Sentry is designed to fill.
2. Instrument the Frontend with Sentry
Install and Initialize the SDK
For a typical browser JavaScript app:
npm install --save @sentry/browser @sentry/tracing
Then, in your entry file (for example index.js or main.ts):
import * as Sentry from "@sentry/browser";
import { BrowserTracing } from "@sentry/tracing";
Sentry.init({
dsn: "https://<your-key>@o<org-id>.ingest.sentry.io/<project-id>",
integrations: [
new BrowserTracing(),
],
tracesSampleRate: 0.2, // adjust based on your volume
});
What this does:
- Installs global handlers for
window.onerrorandunhandledrejection - Listens to exceptions and sends them to Sentry asynchronously (non‑blocking)
- Adds performance tracing if you enable it
Global handlers are based on native browser APIs, and our SDKs are built to be lightweight and have minimal performance impact.
Connect Releases and Source Maps
If your JS is minified (it probably is), you need sourcemaps to make stack traces readable.
- Configure your CI/build pipeline to set a release:
Sentry.init({
dsn: "...",
release: process.env.RELEASE_VERSION, // e.g. from your CI system
});
- Upload source maps to Sentry as part of your build step. For example, with Webpack and the Sentry CLI plugin.
This lets Sentry:
- Show you original filenames, line numbers, and function names
- Tie errors back to a specific release and deployment
Now when a “some users only” error hits, you’re not staring at bundle.js:1:105039.
Add Basic Context and Tags
To better segment “some users” vs “all users,” add custom tags or context:
Sentry.setTag("plan", currentUser.plan); // free, pro, enterprise
Sentry.setTag("feature_flag_beta", enabled); // true/false
Sentry.setUser({ id: currentUser.id, email: currentUser.email });
That’s useful when you discover the bug only affects:
- A specific browser and OS combo
- Users with a particular flag or A/B test variant
- Just mobile Safari on iOS 16, for example
3. Capture the Error in Production
Once the SDK is deployed, you wait for the error to hit in production. When it does, here’s what you get for each event:
- Stack trace (with sourcemaps, if configured)
- Browser and OS: e.g., Chrome 123 / Windows 10, Safari 16 / iOS
- URL and environment: staging vs production, which page, which path
- Release and commit context: which deploy introduced it, suspect commits
- User data (optional): helps correlate “only for some users”
- Breadcrumbs: previous console logs, network requests, navigation events
Even if you’ve never reproduced the bug locally, the production data gives you a concrete path forward.
4. Use Sentry to Isolate “Some Users/Browsers”
Inside Sentry, this is how I filter down to “only some users/browsers” behavior.
Check Issue Details
Open the issue:
- Look at the “Tags” panel: browser, OS, URL, release, environment
- See if one browser dominates the error volume (e.g., 80% Safari on iOS)
- Check release distribution—did it start at a certain version?
This often immediately reveals patterns:
- Only happens in Safari ⇒ likely a feature not supported there
- Only on older Chrome ⇒ maybe an unpolyfilled modern API
- Only in production, not staging ⇒ config discrepancy or different build
Use Discover/Queries
Use Discover (Sentry’s query and analysis feature) to answer questions like:
- “Show me this error by
browser.nameandos.name.” - “Filter events to
browser.name:Safari AND os.name:iOS.” - “Filter by
release:1.8.3to see if it only happens after that deploy.” - “Group by
urlto see where in the app it pops up.”
You’re no longer guessing who is affected. You’re slicing real events.
Correlate with Performance
If you’ve enabled tracing:
- Open the transaction associated with the error
- Check the spans: slow network calls, long scripting time, layout thrashing
- See if the error tends to appear when a specific API endpoint is slow or failing
Sometimes, the JS error is a symptom. The root cause is a backend timeout or a failed fetch.
5. Add Session Replay to See What the User Did
For “only some users/browsers” errors, reproducing the exact click path is half the battle. That’s where Session Replay is powerful.
Enable Session Replay
Install the replay integration (newer SDKs may bundle this; check the docs):
import * as Sentry from "@sentry/browser";
import { BrowserTracing } from "@sentry/tracing";
import { Replay } from "@sentry/replay";
Sentry.init({
dsn: "...",
integrations: [
new BrowserTracing(),
new Replay(),
],
replaysSessionSampleRate: 0.05, // 5% of sessions
replaysOnErrorSampleRate: 1.0, // 100% of sessions with an error
});
What happens:
- Sentry records user sessions for a sample of traffic
- When an error occurs, Sentry keeps the replay for that session
- The replay is linked directly from the error issue
Use Replay to Debug the Edge Case
Open the replay from the issue:
- Watch the user’s actions just before the error
- See clicks, route changes, scrolls, focus/blur events
- Inspect the console logs that occurred on their machine
- See network calls, responses, and failures in the context of the UI
Common patterns we see:
- User navigates away mid‑request ⇒ code that assumes a component is still mounted throws
- A specific widget visible only to some users misbehaves
- A third‑party script fails to load, breaking your integration code
With replay, you’re debugging what actually happened, not what you think happened.
6. Use Ownership and Suspect Commits to Route the Fix
Once you understand the root cause, you need to get it to the right person quickly.
Ownership Rules / Code Owners
Define ownership rules so Sentry auto‑assigns issues:
path:src/components/checkout/** @checkout-team
tag:feature_flag_beta:true @beta-team
Now:
- A bug in
checkout/PaymentForm.tsxautomatically goes to@checkout-team - Errors for beta‑flagged users go to the team running the experiment
This is how you avoid bugs floating in nobody’s backlog.
Suspect Commits and Releases
When Sentry is connected to your repo (GitHub, GitLab, etc.), it:
- Associates errors with releases and commits
- Shows Suspect Commits—commits that most likely introduced the error
That helps in cases like:
- Error appears only in release
frontend@2.5.0 - Sentry shows the commits included in that release
- You see a change that added a new API usage that fails on certain browsers
From there, open a PR, fix the bug, and deploy.
7. Verify the Fix in Production
After the fix is deployed:
- Watch the issue in Sentry:
- Error count should drop for the affected browser/OS
- New events should be tied to the new release
- Set an alert to watch for regressions:
- For example: “Alert when this issue reoccurs more than 5 times in 10 minutes in Safari.”
- If you use an external issue tracker (like Linear):
- Create a Linear issue from Sentry
- When you close it in Linear, have it auto‑resolve in Sentry
You want a clear, data‑backed answer to the question: “Did we actually fix this for those users?”
Frequently Asked Questions
Can I debug these errors without adding anything to my app?
Short Answer: Not reliably.
Details: Browser dev tools are great—for your machine. They don’t give you data from real user sessions on random devices, OS versions, or network conditions. Without a production‑side listener like Sentry, you’re dependent on logs (which often don’t exist) and user reports (which are incomplete at best). Sentry’s JavaScript SDK is a small, non‑blocking listener that captures errors and sends them to Sentry.io with stack traces and context, giving you real data instead of guesses.
Will Sentry slow down my frontend or affect performance?
Short Answer: No—Sentry’s SDK is designed to be lightweight and non‑blocking.
Details: Sentry runs as an error/listener handler in the browser. Events are sent asynchronously, and only when they happen (for example, when an error is thrown, or when a sampled transaction is captured). Global handlers use native browser APIs. In practice, Sentry typically adds negligible overhead to page performance compared to your app’s own JS and third‑party scripts. If you’re concerned about volume, you can tune sampling for tracing and Session Replay so you control exactly how much telemetry you send.
Summary
When a frontend JavaScript error only happens for some users or browsers and not locally, the real problem is missing production context. You’re trying to guess browser, OS, network, feature flags, and user behavior from incomplete reports.
Sentry closes that gap by:
- Capturing real errors from real users in the browser
- Enriching them with stack traces, browser/OS, release, and commit context
- Optionally recording Session Replays so you can watch the exact sequence of actions that triggered the bug
- Routing issues to the right owners and tying them to the code changes that caused them
Instead of “works on my machine,” you get “I see exactly where, why, and for whom it fails—and here’s the fix.”