Issues fingerprinting
How computeFingerprint groups runtime errors into Issues — deterministic rules from ingest.
Fingerprint
A fingerprint is a deterministic SHA-1 grouping key meaning “this is the same bug.” Many raw error events upsert into one Issue row per (project_id, fingerprint).
Runtime errors are fingerprinted on the ingestion server in computeFingerprint after source-map symbolication, so minified frames are normalized to original paths when maps exist.
Runtime algorithm (shipped)
Inputs: exceptionType, value (message), and stackFrames from the SDK error report.
- Prefer in-app frames (exclude
node_modules, browser extensions, and/humanbehavior*.jsSDK files when possible). - Take up to 5 frames.
- For each frame, key
function@normalizedFile— line and column are ignored so small deploys do not split groups. - Basis =
exceptionType+ those frame keys; fingerprint =sha1(basis). - If no usable frames: basis =
exceptionType|normalizedMessage(value)(ids/hex/numbers collapsed).
File normalization
normalizeFile:
- Strips query/hash and URL origin → pathname
- Replaces UUIDs, long hex runs, and digit runs with
*
Message normalization (no-stack fallback)
normalizeMessage collapses UUIDs, hex literals, and digits so "User 12 not found" and "User 99 not found" group together.
Title & culprit
Separately from the fingerprint, ingest derives:
| Field | Rule |
|---|---|
| Title | Type: message (truncated) for the Issues list |
| Culprit | Top in-app frame function (file:line) when available |
What improves grouping / readability
| Practice | Why |
|---|---|
Upload source maps with matching release/dist | Fingerprint keys on original files |
Stable release tags | Releases UI + regressions stay coherent |
| Avoid noisy third-party-only stacks when possible | All-third-party stacks still group, but on vendor frames |
Other issue origins
Fingerprinting above is for runtime crashes (POST /api/ingestion/errors). The Issues product also clusters:
| Origin | Grouping idea (high level) |
|---|---|
| Behavioral | Frustration signals from replay/trace compile |
| Visual | Value-free DOM-structure fingerprints from session states |
| Static | Repo-scan findings with their own deterministic fingerprint |
Those pipelines share the Issues UX but not the same computeFingerprint function as runtime errors.
What creates a “new” Issue
A new fingerprint — typically a different exception type, different top frames after normalization, or a different normalized message when stacks are absent. Pure line-number shifts alone should not split a group.