The two issue types
Exception issues
Grouped by stack-trace fingerprint. One issue covers every occurrence of the same bug across every request, job, or command that hit it.
Performance issues
Opened automatically when a single record’s duration crosses a threshold you configure in Settings → Thresholds. Thresholds cover routes, queries, jobs, commands, cache, mail, notifications, outgoing requests, and scheduled tasks.
Status model
An issue is always in one of three states:| Status | Meaning |
|---|---|
open | Active. Alerts fire and the issue appears in the default list. |
resolved | Fixed. Silent until the fingerprint recurs — at which point the agent auto-reopens it (regression detection) and fires issue.reopened. |
ignored | Noise. Silenced indefinitely — never auto-reopens, regardless of how often the fingerprint recurs. |
Triage workflow
- Filter down — status pills (Open / Resolved / Ignored / All), environment dropdown, assignee dropdown, and free-text search stack across each other.
- Pick by priority — the priority column is sortable. Critical first, then high.
- Open the detail view — click a row. The right-hand Manage sidebar has status, priority, assignee, and description; the main pane shows the latest stack trace, occurrence sparkline, affected users, environments, and a combined comments + activity timeline.
- Resolve with context — post a comment and tick Resolve on comment in one action. The comment, the status flip, and the alert fan-out all happen together.
Bulk actions
Tick the checkbox on multiple rows to reveal the bulk toolbar. Available actions:- Resolve selected
- Ignore selected
- Reopen selected
Assignments and comments
- Assignee — any team member on the app. Assigning an issue notifies the assignee through the configured alert channels (if they have email configured).
- Comments — markdown supported. Use them to document the investigation, link to PRs, or record why something was ignored.
- Activity timeline — every status change, priority bump, assignment, comment, and description edit appears in the timeline. Entries from the MCP server are visually distinct so AI-driven edits stay auditable.
Alerts
Alert channels fire on the four lifecycle events documented in Alert channels → What fires an alert:issue.new (brand-new fingerprint), issue.reopened (a resolved issue’s fingerprint recurs — the agent flips it back to open automatically), plus issue.resolved / issue.ignored / issue.reopened on user triage actions.
Individual occurrences within an already-open or already-ignored issue never re-alert — they bump counters silently. That keeps Slack quiet during incident storms and keeps “ignored” meaningful. resolved is the exception: a recurrence is treated as a regression, so the agent auto-reopens the issue and fires issue.reopened.
To suppress flapping, set NIGHTOWL_REOPEN_COOLDOWN_HOURS on the agent (see Configuration → Issue lifecycle). With a cooldown of 24, for example, an issue resolved less than 24 hours ago stays silent on recurrence; only after the cooldown elapses does the next recurrence trigger the auto-reopen.
Auto-resolve stale issues
In Settings → Issues you can set an auto-resolve window (default: disabled). Anyopen issue with no new occurrences for that many days is resolved automatically by the nightowl:auto-resolve-issues artisan command, scheduled via Laravel’s scheduler in each app.
This keeps long-running projects from accumulating a graveyard of open-but-forgotten issues. The activity timeline still shows exactly when and why the auto-resolve happened.
API and automation
Every action in the UI — status change, priority edit, comment, bulk update — has a direct API equivalent under/data/{app}/issues. AI assistants can do the same through the MCP server, which wraps those endpoints with auditable tokens and a fixed tool surface.