How to find out which customers hit a Sentry error
Open the issue, and Sentry shows you "14 users affected." Open the tags on that issue, and if you've called setUser() in your SDK, you can see the individual user.id, user.email, or user.username values behind that number. What Sentry can't tell you is which of those users are on your enterprise plan, which are up for renewal next month, or whether they're all from the same account. Sentry tracks users. It has no concept of a company.
Getting from "14 users" to "which customers" takes two things: user context that's actually being set on your events, and something outside Sentry that knows which user belongs to which account. Here's how each piece works, and where the manual version stops being fast enough.
Step 1: confirm you're capturing user identity at all
Sentry's user context docs are explicit that this isn't automatic: you call Sentry.setUser({ id, email, username }) yourself, typically right after your app knows who's logged in. Skip that call and every event on the issue shows no user at all, no matter how much traffic the endpoint gets.
This is the step that quietly breaks. Auth flows change, a new client gets added that never wires up the SDK, or setUser() runs before the session is hydrated and fires with an empty object. Before trusting an issue's "affected users" count, spot check a few recent events and confirm the user field is populated. If it's empty on any meaningful fraction of events, everything downstream of this guide is working from a fraction of the real picture.
Step 2: pull the affected users off the issue
Once identity is attached, Sentry's search syntax treats user.id, user.email, and user.username as first-class searchable fields. From an issue, filter by user.email:* to see distinct values, or search across your whole project for user.email:jsmith@example.com to find every issue a specific person has hit.
That gets you a list of identifiers. It does not get you a list of customers, because nothing in that list says which company each email belongs to. A support engineer looking at jsmith@example.com, t.reyes@wharfline.io, and k.okafor@wharfline.io has to already know, or go look up, that two of those three are the same account.
Step 3: attach an account identifier yourself, if you can
If your app knows the customer's company at the point where errors originate, Sentry's context and tags let you attach it directly: Sentry.setTag('account_id', org.id) alongside setUser(). Tags are searchable the same way user fields are, so account_id:wharfline becomes a valid filter once it's wired up.
This is the honest fix for teams that control the client and have a stable org identifier available at error time. It's also extra instrumentation to add and keep current as your auth model changes, and it only covers errors captured after you ship it. Issues from last month still only have user IDs.
Worked example: an on-call engineer who needs the account list, not the user count
Tomás Reyes is a staff engineer at Wharfline, a freight-tracking platform. A new Sentry issue fires overnight: TypeError: Cannot read properties of undefined (reading 'weightKg') in the rate-calculation service, 340 events, 22 users affected. By the time he's at his desk, an account exec has already pinged the on-call channel.
Priya (AE): Is this the bug affecting Meridian Freight? They're renewing Friday and their ops lead just asked about it in our shared Slack channel.
Tomás opens the issue and filters by user.email:*meridianfreight*. Four matches. He now knows Meridian hit it, but he still doesn't know if those four users are Meridian's whole ops team or a fraction of it, whether any other renewal-week accounts are in the other 18 users, or whether this is the same bug the ops lead described in Slack or a different one that happens to throw the same error.
Tomás: Confirmed, 4 of their users hit it overnight. Checking the rest of the list for other accounts at risk now, give me a few minutes, it's a manual cross-reference against the customer list.
That "few minutes" is the real cost. Sentry did its job: it caught the error and preserved the identifiers. The account lookup, the cross-reference against renewal dates, and the connection to what the ops lead already said in Slack all happen in Tomás's head and a spreadsheet, and none of it is saved anywhere for the next person who asks the same question about the next issue.
Where the manual cross-reference stops working
The setup above scales fine for one issue and one urgent question. It breaks down predictably:
- The lookup doesn't persist. Tomás's answer lives in a Slack reply. The next engineer who touches this issue redoes the same email-to-company matching from scratch.
- Sentry's user list and your support/sales conversations are separate systems. Knowing that four Meridian users hit the bug doesn't tell you what their ops lead already said about it in Slack, or whether a support ticket describes the same symptom in different words.
- It doesn't scale past a handful of affected users. Twenty-two users across an unknown number of accounts means twenty-two manual lookups, every time, for every issue that matters enough to ask about.
That's the point where cross-referencing errors against account data stops being a five-minute favor and becomes a standing job nobody signed up for. It's also the layer Modem works on: Modem's Sentry integration reads issues, stack traces, and the user identifiers on them, resolves each one to a person and the company they belong to, and shows what that same account has said elsewhere (a Slack thread, a support ticket, a call transcript) next to the error. The question Priya asked, is Meridian affected, becomes a lookup instead of a spreadsheet exercise, because the person-to-company join already happened before anyone asked. We build Modem, so weigh that against the comparison in our roundup of tools that connect Sentry errors to customer feedback, which covers four other approaches to the same gap.
The underlying idea, a graph that keeps people linked to their companies and their companies linked to what they've said, is covered on its own in what a customer context graph is. None of this replaces setUser(); Modem still needs Sentry to have captured an identifier in the first place, so step 1 above stays your job regardless of what reads the data afterward.
The smallest version you can start this week
Confirm setUser() fires on every authenticated request path, not just the main one. Then, for the next issue with more than a handful of affected users, do the email-to-company match once and write the account list into the issue as a comment before you close it. That alone means the next engineer who opens it isn't starting from zero.
