Errors for AI agents
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 whycreated.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:TypeErrormatches either. This is the only way to express OR — there is noORoperator. - Repeating a negated key excludes every listed value:
-environment:staging -environment:developmentexcludes 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#actionis shorthand forcomponent: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.comcreated— 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:andhas: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:meresolves server-side to the current user;assignee:anybodyandassignee:nobodymatch 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
redisisclass:redis, notclass:Redis). - User identity lives in the error context —
context.user_idandcontext.user_emailby 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:countdoes 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 anenvironment:filter, “last deploy” resolves to that environment’s latest deploy.- Do not add upper bounds that are always true:
.before:NOWor[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.