# Errors ## The error model Honeybadger groups error occurrences by fingerprint: a *fault* is one unique error within a project, and each occurrence of it is a *notice*. A fault carries the error class, message, component/action, environment, tags, and an optional assignee; its notices carry the occurrence details (backtrace, request, params, context, session, hostname, revision). Occurrences are also emitted as `notice` events on the project's internal Insights stream, so error data is queryable with BadgerQL too (see the queries instructions — Streams). ## Lifecycle and states - **Unresolved** — the default state; the error is open. - **Resolved** — marked fixed. If the error occurs again it automatically REOPENS (resolved is cleared) and a notification is sent — resolving is not permanent suppression. By default a deploy also auto-resolves every open error in its environment (`resolve_errors_on_deploy`, on by default, per-project) — which is why `created.after:"last deploy"` is the idiomatic "new errors" triage window. - **Ignored** — new occurrences are DISCARDED (not recorded as notices) and never notify, until unignored. The fault and its existing history remain. - **Paused** — notifications are snoozed for a duration (hour/day/week) or until the error occurs N more times (10/100/1000). Occurrences ARE still recorded — pausing silences the noise without losing data. - **Pending resolution** — marked to resolve automatically at the next deploy. Processed on every deploy regardless of the auto-resolve setting — the per-fault alternative when project-wide auto-resolve is off. - **Assigned** — a user (by email) owns the fault. Recording can also be paused outright until a set time — occurrences are discarded during the pause, and the first occurrence after it expires notifies. This is separate from the notification pause above and has no search filter. ## Search The same search string is accepted everywhere errors are filtered: the error list UI, the `errors` dashboard widget's `query` field, and the Data API's `q` parameter on the faults endpoints. ### Syntax - Combine filters with spaces; different keys must all match (AND). - REPEATING a key ORs its values: `class:NoMethodError class:TypeError` matches either. This is the only way to express OR — there is no `OR` operator. - Repeating a negated key excludes every listed value: `-environment:staging -environment:development` excludes both. - Bare terms (no `key:`) full-text search the error class and message, ANDed with the other filters: `stripe class:PaymentError`. - Negate a filter with a leading `-`: `-is:resolved`. Not every key is negatable — see the reference. - Quote values containing spaces: `message:"undefined method"`. - `component#action` is shorthand for `component:X action:Y`: `users_controller#show`. ### Values and wildcards - `*` anywhere in a value is a case-insensitive contains match: `context.user.email:*@example.com`, `request.url:*checkout*`. - `key:*` alone is a presence check — any non-empty value: `context.user_id:*` finds errors with a user attached. - Array elements are addressed by index in the key path (`params.job.args.0.job_id:123`), or matched anywhere in the array with a wildcard value (`params.job.args:*Foo*`). ### Filter reference - `class` — Filter by class. Example: `class:value` (negatable with `-`) - `component` — Filter by component. Example: `component:value` (negatable with `-`) - `action` — Filter by action. Example: `action:value` (negatable with `-`) - `environment` — Filter by environment. Example: `environment:value` (negatable with `-`) - `is:assigned` — Errors that are assigned. Example: `is:assigned` (negatable with `-`) - `is:ignored` — Errors that are ignored. Example: `is:ignored` (negatable with `-`) - `is:resolved` — Errors that are resolved. Example: `is:resolved` (negatable with `-`) - `is:paused` — Errors that are paused. Example: `is:paused` (negatable with `-`) - `is:pending_resolution` — Errors that are pending_resolution. Example: `is:pending_resolution` (negatable with `-`) - `has:ticket` — Errors that have ticket. Example: `has:ticket` (negatable with `-`) - `has:tickets` — Errors that have tickets. Example: `has:tickets` (negatable with `-`) - `has:comment` — Errors that have comment. Example: `has:comment` (negatable with `-`) - `has:comments` — Errors that have comments. Example: `has:comments` (negatable with `-`) - `tag` — Filter by tag. Example: `tag:"foo"` (negatable with `-`) - `assignee` — Filter by assignee email; also accepts assignee:anybody, assignee:nobody, assignee:me (resolved server-side to the current user's email). Example: `assignee:user@example.com` - `created` — Lucene-style range on first-seen date. Example: `created:[NOW-1DAY TO NOW]` (negatable with `-`) - `created.before` — First seen before a date. Example: `created.before:"24 hours ago"` (negatable with `-`) - `created.after` — First seen after a date. Example: `created.after:"last deploy"` (negatable with `-`) - `last_occurred.before` — Last occurred before a date. Example: `last_occurred.before:"1 hour ago"` - `last_occurred.after` — Last occurred after a date. Example: `last_occurred.after:"1 week ago"` - `occurred` — Lucene-style range on any occurrence date. Example: `occurred:[NOW-1DAY TO NOW]` (negatable with `-`) - `message` — Filter notices by error message text. Example: `message:"undefined method"` (negatable with `-`) - `file` — Filter notices by file path. Example: `file:app/models/user.rb` (negatable with `-`) - `hostname` — Filter notices by hostname. Example: `hostname:web-1` (negatable with `-`) - `revision` — Filter notices by revision sha. Example: `revision:abc123` (negatable with `-`) - `request.*` — Filter notices by request fields (url, referer, user_agent, etc.). Example: `request.url:example.com` (negatable with `-`) - `params.*` — Filter notices by request params. Example: `params.user_id:42` (negatable with `-`) - `context.*` — Filter notices by context fields. Example: `context.tenant:foo` (negatable with `-`) - `session.*` — Filter notices by session fields. Example: `session.id:abc` (negatable with `-`) ### Semantics and traps - The default error list excludes resolved and ignored faults. A search for "what's broken" should include `-is:resolved -is:ignored`; drop them only when resolved or ignored errors are explicitly wanted. - Use `is:` and `has:` values exactly as enumerated in the reference (`is:resolved`, `is:ignored`, `is:assigned`, `is:paused`, `is:pending_resolution`, `has:ticket`, `has:comment`). Do not invent other values. - Never invent filter keys. An unrecognized filter does NOT error — the whole token silently becomes a full-text search over class and message, which usually matches nothing. The wildcard prefixes (`request.*`, `params.*`, `context.*`, `session.*`) accept any subkey, but only use subkeys known to exist in the project's data. - `assignee:` takes an email address. `assignee:me` resolves server-side to the current user; `assignee:anybody` and `assignee:nobody` match presence/absence of an assignee. A bare name (`assignee:bob`) is never valid. - Use class names as given; do not normalize casing (a search for `redis` is `class:redis`, not `class:Redis`). - User identity lives in the error context — `context.user_id` and `context.user_email` by convention (the tracked field is configurable per project). "Errors affecting user X" → `context.user_email:x@example.com`; "errors that affected any user" → `context.user_id:*`. - There is NO sort token — `sort:count` does not exist. Sorting is a separate UI/API parameter (`order`: `recent`, `frequent`), never part of the search string. ### Time filters - For relative periods, use the `.after:` forms: `last_occurred.after:"24 hours ago"` (most recent occurrence), `created.after:"1 week ago"` (first seen — new errors), `occurred.after:"24 hours ago"` (any occurrence in the window). - For errors that have NOT happened recently, use `last_occurred.before:` — "errors that haven't occurred in a month" → `last_occurred.before:"1 month ago"` (the most recent occurrence is older than a month). Do not reach for a negated `.after:` — `last_occurred.*` is not negatable, and the unrecognized token silently degrades to a full-text search. - Date values are parsed as natural language: `"24 hours ago"`, `"today"`, `"july 1"`, `"now"`, ISO timestamps, and the special value `"last deploy"`. - `created.after:"last deploy"` matches faults first seen since the latest deploy; combined with an `environment:` filter, "last deploy" resolves to that environment's latest deploy. - Do not add upper bounds that are always true: `.before:NOW` or `[X TO NOW]` is redundant for one-sided "since X" ranges — use `.after:` instead. Use the bracketed Lucene range form (`created:[NOW-7DAY TO NOW-1DAY]`) only when both bounds are meaningful.