Skip to content

[[route]]

A [[route]] sends matching events to a list of notifiers. Use it when one rule should cover many tasks, or for outcomes other than failures. For one task’s failures, notify on the task is simpler.

# Every failure goes to the team channel
[[route]]
match = { failure = true }
notifiers = ["slack-ops"]
# Backups also page on-call
[[route]]
match = { failure = true, task = "backup-*" }
notifiers = ["tg-oncall"]
# Deploys announce success
[[route]]
match = { task = "deploy", kinds = ["succeeded"] }
notifiers = ["slack-ops:#deploys"]

An event can match several routes, plus the task’s own notify and global_notifiers. RunWisp collects every matching notifier and sends one message to each. Route order doesn’t matter.

Changing a route needs runwisp restart; reload rejects it.

type: table default: {} (every event)

All set fields must match.

type: boolean

true matches any run counted as a failure by the task’s failures list.

type: string[] default: all kinds

The outcomes to match. Uses the same names as failures:

  • started: a run starts (only sent when listed here)
  • succeeded: a run exits 0
  • failed: a run exits non-zero or is killed by a signal
  • timeout: stopped by timeout
  • crashed: still running when the daemon itself was killed
  • log_overflow: stopped by log_on_full = "kill"
  • unhealthy: a service instance stopped for failing its health_check
  • queue_full: dropped because max_queued was reached
  • stopped: stopped by an operator or on_overlap = "kill"
  • daemon_stopped: cut short by daemon shutdown
  • missed: a scheduled run was missed while the daemon was down
  • service.fatal: a service gave up after restart_attempts
  • log.disk_pressure: free disk fell below min_free_space

notify.delivery_failed always goes only to the bell; listing it here is an error.

type: string (glob) default: every task

A shell-style glob on the task or service name: * (any run of characters), ? (one character), [abc] (one of these). Case-sensitive. No {a,b} braces.

[[route]]
match = { task = "backup-*", kinds = ["timeout"] }
notifiers = ["tg-oncall"]

type: string[] required, at least one

Where matching events go. Each entry is one of:

  • a notifier id declared in a [notifiers.<id>] block, like "slack-ops"
  • "inapp", the bell
  • "<id>:<target>", which reuses that notifier’s credentials but sends to another target: a Slack channel ("slack-ops:#deploys", "slack-ops:@ana"), a Telegram chat id ("tg:-1009998887"), or an email address for smtp and sendmail ("mail:[email protected]"), an ntfy topic ("phone:backups"), or a Pushover user or group key ("po:gznej3rKEVAvPUxu9vvNnqpmZpokzF"). Discord, Gotify, and webhook notifiers take no target.

The config fails to load with any of these:

  • A notifier id that isn’t declared and isn’t "inapp".
  • An empty notifiers list.
  • An unknown match.kinds value (including notify.delivery_failed), or a match.task glob that can’t be parsed.
  • An <id>:<target> whose notifier isn’t declared, whose target is empty, whose notifier type takes no target, or, for Slack, whose target doesn’t start with # or @.
  • "inapp:<anything>": the bell has no target.