Debugging 2026-06-25

Bugs That Only Happen to One User

Five things cause almost every bug that affects exactly one user:

  1. The shape of their data
  2. The shape of their permissions
  3. Corrupted state on their machine
  4. A browser extension interfering with your page
  5. Their locale or timezone

That list is the most useful thing in this article, so it goes first. When you need to debug a user specific issue — the report that ends with “but it works fine for everyone else, including us” — you are almost certainly looking at one of those five, and the investigation is a process of elimination among them. Everything below is detail: what each category looks like from the inside, and the sequence that finds the culprit without guessing.

One framing note before the detail. “Works for everyone else” is a statement about your accounts, and your accounts are unrepresentative in every way that matters. They’re new-ish, small-ish, admin-roled, English-locale, extension-free, and logged in from clean browsers. The one user’s bug isn’t spooky. Their account simply occupies a corner of configuration space that none of yours do.

The taxonomy

Data-shape bugs

Their account has 4,000 items; yours has 12. That single difference breeds a whole family of failures: the query that’s fine at 12 rows and times out at 4,000; the unpaginated endpoint whose response now exceeds a body-size limit; the frontend list that renders 12 nodes instantly and locks the tab at 4,000; the export that dies quietly past some threshold nobody remembers choosing.

But volume is only the loudest version. Data-shape also means the customer whose records predate your 2023 migration and carry nulls in a column you made required afterward. The user whose name contains a character your PDF library can’t encode. The organization with a hierarchy nested six levels deep when every test fixture nests two. Old accounts are archaeological sites — they contain strata of every schema decision you’ve ever walked back.

In my experience this category is the plurality of one-user bugs, and it’s also the most satisfying to fix, because the reproduction is sitting right there in their data once you look at it.

Permission edge cases

Your team tests as admins. Admins see every button, pass every check, and traverse every code path without friction — which means the viewer who belongs to two workspaces, or the member whose role was changed mid-session, or the user granted access to a resource whose parent they can’t see, is traversing paths nobody has exercised deliberately in months.

The classic symptom is the half-rendered page: the UI showed a button the permission model wouldn’t honor, or hid a container the code assumed existed. If the affected user’s role is anything other than admin-of-one-workspace, suspicion should rise sharply.

Corrupted local state

Everything server-side is identical for this user, and the bug follows their browser, not their account. Stale localStorage from a version three releases ago. A cached service worker serving last month’s JavaScript against this month’s API. A JWT that refreshes wrong in some edge case.

The diagnostic tell is the inverse of the account test: if the user logs in on a different machine and the bug vanishes, you’re in this category. It’s the one category where “clear your cache” is legitimate — but as a diagnosis, not a fix. If clearing storage resolved it, you have a state-migration bug that will hit others; schedule the real fix rather than closing the ticket.

Extension interference

Ad blockers eating your analytics or replay script. Password managers injecting DOM nodes into your forms. Translation extensions rewriting the text your click handlers match on. Coupon extensions doing things to checkout pages that defy summary.

The page the user experiences is not the page you shipped, and no amount of staring at your own code will reveal a mutation performed by software you’ve never heard of. Suspect this category when the bug is visual or interaction-level, follows the browser profile, and disappears in a clean profile on the same machine.

Locale and timezone

The user in UTC+13 for whom “today” is already tomorrow, breaking a date filter that compares against server midnight. The DST transition that makes an hour ambiguous and a scheduled report fire twice. The decimal-comma locale that turns “1.500” into a validation dispute. Week-starts-on-Sunday versus Monday quietly shifting a chart’s buckets.

These masquerade as intermittent bugs because they’re time-gated: the report from the Auckland user reproduces perfectly — but only if you reproduce it as the Auckland user, timezone and all. If the bug involves a date, a schedule, or a number format anywhere near its blast radius, check this category before the exotic ones.

Debug a user specific issue: the sequence

The taxonomy tells you what to suspect. The sequence tells you what to do, in order, without burning the user’s patience.

First, search your sessions for their identity. If you run session replay with user identification, this is the single highest-value move: pull up the affected user’s recent sessions and watch the failure happen. Tools like LogReplay index sessions by user email and attach the console and network trail to the same timeline, so five minutes of watching often settles which taxonomy branch you’re on — a red network entry says data or permissions; a pristine console with a dead button hints at extensions or local state. Without replay, substitute the closest evidence you have: their error-tracker events, their server logs filtered by user ID.

Second, compare against a working account — attribute by attribute. Take the affected account and a healthy one and diff them like configurations, because that’s what they are: role and workspace memberships, record counts, account age, plan and feature flags, locale and timezone, and any “unusual” data (nulls, extreme values, odd characters) in the tables the broken feature touches. You’re hunting for the attribute where the two accounts diverge. Most of the time, one or two candidates jump out immediately — the account is ten times bigger, or the role is one you forgot existed.

Third, bisect the difference. Take the most suspicious divergence and test it in isolation: clone a healthy test account and mutate one attribute toward the broken account’s value. Bulk-load it to 4,000 items. Flip the role to viewer. Set the profile timezone to Pacific/Auckland. If the bug appears, you’ve converted a one-user mystery into an ordinary reproducible defect, and normal debugging takes over from there. If it doesn’t, return the attribute, mutate the next candidate, repeat. It’s bisection over configuration space instead of over commits, and it converges just as reliably.

If you exhaust server-side attributes without a reproduction, the bug lives on the client — which means it’s local state or extensions, and the conversation with the user changes accordingly. Now you’re justified in asking for one clean test: same account, different browser profile. One ask, high information, and you know which of the two client categories you’re in based on the answer.

Resist the “just one user” close

The pull to deprioritize these bugs is real, and on any given afternoon, defensible. But “one user” is a measurement, not a fact. It usually means one user reported it — the others hit it and left, or worked around it, or haven’t aged into it yet. Every account will eventually have 4,000 items. Data-shape bugs, especially, are early warnings from your most engaged customers, which is exactly the population you can least afford to teach that reporting bugs is pointless.

There’s also a compounding skill argument. Each of these investigations makes your team faster at the next one, because the taxonomy stops being a blog post and becomes a reflex. And the intake side improves too — the difference between a dead-end report and a solvable one is usually whether anyone captured the right details up front, which is a skill of its own. The habits in turning vague bug reports into reproductions are what get you the account identifier and the timestamp that step one of the sequence depends on.

One user today. The account shape of your whole customer base in a year. Fix it while it’s cheap.

See the bug the way your user did

LogReplay captures session replays, console output, network requests, and errors in one timeline — so you stop guessing what happened before the ticket arrived.

Try LogReplay free