Error Grouping
How ErrTap groups events into issues using fingerprints, and how to control grouping, statuses, and severity.
How events become issues
Events become issues by fingerprint. By default ErrTap normalizes each error — addresses, UUIDs, numbers, and string literals are masked — then hashes the error type plus the top stack frames. This means user 41 not found and user 87 not found group together into one issue.
Fingerprinting
When the default grouping gets it wrong, pass a fingerprint from any SDK to take control:
captureException(e, { fingerprint: 'checkout-payment-failure' });Same key → one issue, regardless of message or stack. Different keys → separate issues.
Merging issues
Sometimes one bug produces several issues — different call sites, or a message that varies more than the fingerprint can normalize. Select them in the issue list and choose Merge: they fold into the one with the most events. Events, comments and counts move over, and future events with any of the merged fingerprints keep landing in the surviving issue.
Tag distribution
Each issue page shows how its most recent events (up to 10,000) split across environment, release and every tag you send — so "only on Safari 17" or "started in release 2.4.1" stands out without opening events one by one.
AI root-cause analysis
On an issue page, Analyze with AI sends the issue to an OpenAI model with its latest stack trace, tags, event distribution across releases and environments, other stack shapes seen, and what affected users reported. You get a short summary, the likely cause with the evidence behind it, a suggested fix, a confidence level and what to check next. The result is saved on the issue for the whole team; Re-run refreshes it.
Only owners, admins and developers can run an analysis, and nothing is sent until someone clicks. Each plan includes a monthly allowance per organization:
| Plan | Analyses / month |
|---|---|
| Hobby | 5 |
| Pro | 50 |
| Team | 100 |
| Enterprise | 500+ |
The card on each issue shows how many are left this month; runs that fail or that the model declines don't count. Events are sent after your project's PII scrubbing, and requests are made with storage off so OpenAI doesn't keep them for later retrieval. Self-hosted installs enable it by setting OPENAI_API_KEY (and optionally OPENAI_MODEL).
Issue statuses
| Status | Meaning |
|---|---|
open | Active — new events are arriving |
acknowledged | Seen and being worked on; new events keep it acknowledged and don't reopen it |
resolved | Marked resolved by hand; reopens as a regression when the error comes back in a later registered release, or on any new event if the project had no release records when it was resolved. See Regression behaviour |
ignored | Suppressed — events still ingest but the issue won't alert or surface in the default view |
snoozed | Ignored until the snooze ends; the first event after that reopens it as a regression |
Severity levels
Events carry a level field:
| Level | Description |
|---|---|
error | Default — a caught or uncaught exception |
warning | Degraded behaviour, non-fatal |
info | Informational; used with captureMessage |
Severity is passed at capture time:
captureMessage('payment fallback used', { level: 'warning' });Issues inherit the highest severity level seen across their events.