Issues and failure fingerprints
A thousand failed task runs are usually a handful of actual bugs. z4j fingerprints every task failure and groups tasks by fingerprint into issues: one row per distinct logical failure on a project, with its occurrence count, whether it is still happening, and which engines it spans.
What a fingerprint is
Section titled “What a fingerprint is”A fingerprint is a stable hash of a failure’s shape:
- the exception class (z4j stores the class name, not the message),
- plus the deepest five traceback frames, each reduced to
file:line:function.
The deepest frames are used because they are the most distinctive; the top of a deep stack is mostly framework boilerplate. Volatile noise is stripped before hashing, so the same bug cannot splinter into many fingerprints: hex memory addresses, UUIDs, object reprs, and bare long numeric ids are all normalised away. A traceback with no parseable Python frames falls back to hashing its noise-stripped text.
The result is a 32-hex-character value, computed once when the
task.failed event is ingested and stored on the task row. It is pure
and deterministic: the same failure hashes identically across
processes, restarts, and brain replicas.
Line numbers are deliberately kept: a code change that shifts the failing line produces a new fingerprint. A new deploy’s bug is a new issue, even when the exception class is the same.
Open vs recovered
Section titled “Open vs recovered”A task keeps its fingerprint from its most recent failure, even after a later retry succeeds. That split is what makes an issue’s status meaningful:
- ongoing: at least one task carrying the fingerprint is currently
in the
FAILUREstate. - recovered: every task that ever hit the fingerprint has since succeeded (or otherwise left the failure state).
An issue’s first/last-seen timestamps are anchored on when the tasks failed, not on when they finished, so an old failure that recovered recently does not masquerade as a fresh problem.
The issues endpoint
Section titled “The issues endpoint”GET /api/v1/projects/{slug}/issuesRole: viewer. An issue is operational data about tasks a member can
already read (no who-did-what), so any project member can list them.
Query params: engine, status (ongoing | recovered), hours
(time window, 1..8760), cursor, limit (default 50, max 200).
{ "items": [ { "fingerprint": "9f2c4a1e8b7d63051a2f4c8e9b0d7a31", "status": "ongoing", "occurrences": 412, "open_count": 37, "recovered_count": 375, "first_seen": "...", "last_seen": "...", "engine_count": 2, "engines": ["celery", "rq"], "sample_exception": "IntegrityError", "sample_task_name": "billing.close_invoice" } ], "next_cursor": null}occurrences counts the tasks that hit the fingerprint; open_count
is how many of them are failing right now. Issues are ordered by
last_seen, newest first. The engine and hours filters apply to
the aggregation itself, so the counts and the engines list always
agree with the filter.
Fingerprints as automation conditions
Section titled “Fingerprints as automation conditions”fingerprint is an exact-match condition key in
automation rules. That turns “this one known
bug keeps failing” into a precise, narrow trigger:
- List the project’s issues and copy the fingerprint of the failure you care about.
- Create a
task.failedrule with afingerprintcondition set to that value, and the action you want (notify, or a governedretryfor a known-transient failure). - Arm it as dry-run first and watch the audit log to confirm it matches exactly the events you expect.
Because the rule keys on the noise-stripped failure shape rather than on task name or exception substrings, it will not fire on unrelated failures that happen to share a task name, and it will stop matching when a deploy moves the failing line (new fingerprint, new issue), which is usually what you want from a bug-scoped rule.
See also
Section titled “See also”- Automation rules for the full rule grammar and governance model.
- Redaction for how exception and traceback data is scrubbed before it is stored (fingerprints are computed from the scrubbed form).