Create a workflow or scheduled task
Everyone · Automate the work
Better authoring, same executor
v0.5.18 gave workflows a real visual editor — forms, trigger filters, template autocomplete, a warning before you activate something noisy. None of that changed how runs execute. Scheduled workflows are still unreliable, and the characteristic failure is still an agent describing the task it was supposed to perform, convincingly, instead of performing it. The editor makes it easier to build the thing that fails quietly. Build the verification in from the start.
Steps at a glance
1. Decide whether the work can survive silent failure
Ask what happens if this runs and quietly does nothing for two weeks. If the answer is "we would notice immediately", automate it. If the answer is "we would find out from a client", do not — or automate it with a checker attached.
Good candidates: nudges, digests, prompts that a human then acts on. Poor candidates: anything that is the only thing standing between a project and a missed commitment.
2. Turn on the experimental features
Workflows sit behind an experiments toggle in Settings.
The label means exactly what it says. Treat everything behind it as provisional — including the editor, which is new.
3. Choose the trigger, then narrow it with a filter
Five trigger types, not four. diff_posted joined the set:
| Trigger | Fires when | Filter |
|---|---|---|
| Message posted | any message lands in the workflow's channel | yes |
| Reaction added | an emoji reaction is added to a message | yes, plus an optional specific emoji |
| Diff posted | a diff message is posted in the channel | yes |
| Schedule | a cron expression (UTC) or a simple interval such as 1h or 30m |
— |
| Webhook | an HTTP POST arrives at the workflow's hook URL | — |
Reaction triggers remain the most underrated of the five — a human adds an emoji and the workflow fires, which puts a person in the loop by construction rather than by policy. Leaving the emoji unset matches any reaction.
The editor now offers structured trigger filters: conditions built in the form rather than hand-written expressions, with validation that blocks an invalid workflow from being saved. Advanced expressions you write yourself are preserved rather than rewritten. Filtering at the trigger is worth the two minutes — an unfiltered message trigger fires on every message in the channel, including the agent's own replies.
Webhook triggers let external systems push work in, and are reported as the least stable of the five. See Integrate an external data feed.
4. Build the workflow in the editor
Workflows are scoped to a channel and edited in a route-addressable editor with two modes:
- Form — fields, dropdowns, structured conditions, and autocomplete in message text.
- YAML — the underlying definition.
Switching between them is lossless in both directions, and YAML the form does not understand is preserved rather than dropped. You can duplicate an existing workflow, deep-link to one, and the editor warns before you leave with unsaved changes.
Template variables are available in message text, with caret-aware autocomplete that offers what is actually in scope: values from the trigger, and outputs from earlier steps. {{trigger.text}}, {{trigger.author}}, {{trigger.message_id}}, {{trigger.channel_id}}, {{trigger.timestamp}}, {{trigger.emoji}}, {{trigger.is_reply}} and {{steps.<id>.output.<field>}}, with filters such as truncate(n) and npub. These resolve locally and deterministically — nothing is fetched to fill them in.
Actions available to a step: send a message (to the channel, to another channel, or in-thread as a reply to the triggering message), send a DM, set the channel topic, add a reaction, call a webhook, request approval, or delay.
Where the reference lives
There is still no user-facing YAML reference in the documentation. The form side of the editor is now the closest thing to one — it enumerates the triggers, actions and fields that exist, which is what a reference would have told you. For anything the form does not cover, the schema in crates/buzz-workflow/src/schema.rs is the source of truth.
Keep the first one small. A workflow that does one thing can be diagnosed; one that does five cannot.
5. Read the activation warning before you switch it on
Saving a workflow does not run it. Activating it does, and since the workflow-setup pass the editor shows a risk-aware warning before you turn on anything whose trigger is likely to fire often — a broad message trigger with no filter being the usual case.
Take the warning literally. A workflow that fires on every message and posts a message is a loop, and the run history will show you exactly how fast.
Workflow cards also carry a semantic summary — a plain reading of what the workflow will do — so you can audit the library without opening each one.
6. Verify the run, then verify the verification
Check the run trace after the first execution. Run history in the desktop app is authoritative and failed runs carry machine-readable error codes — trust the trace for whether a run failed and why.
Then check the effect, not the trace. A run marked complete where nothing happened is the failure mode you are guarding against, and even the improved trace will not tell you.
For anything recurring, pair it with a task-checker agent whose only job is confirming the work actually happened. See Set up a lead agent and delegation pattern.
If your workflow includes an approval step, read Approve or deny a workflow approval step first — those steps still fail the run.
Verified against Buzz v0.5.20 · Updated 2 Sep 2026