Summary
A workflow definition's enabled field parses, validates, round-trips through the relay, and does nothing. The scheduler reads the enabled table column, which the definition never writes. A user who "disabled" a workflow by editing its YAML still has it running on schedule, and every surface they can check says it is disabled.
This fails in the direction users care about: silently keeping something running that they believe they turned off.
Where
// crates/buzz-db/src/workflow.rs
pub async fn list_all_enabled_workflows(pool: &PgPool) -> Result<Vec<WorkflowRecord>> { // :457
// ...
AND w.enabled = TRUE // :465
enabled is a column (:290, in the INSERT column list alongside definition), and the only writer is set_workflow_enabled() (:684), reachable through its own API. The definition blob — where the YAML enabled: lives — is never consulted by the scheduler query. Verified present at HEAD.
Reproduction
- Create a workflow with a
schedule trigger.
buzz workflows update it with a definition whose top level contains enabled: false.
- The relay accepts the update (
{"accepted":true}) — no warning, no validation error.
- Query the row:
enabled is still t.
- The workflow fires on its next cron tick.
Observed on a self-hosted relay at v0.5.3.
Why this is worse than a no-op field
The field looks authoritative. It is at the top level of the definition next to name, description, and trigger, all of which are honoured. It survives a round-trip, so workflows get echoes back enabled: false — which reads as confirmation that the setting took effect. There is no diagnostic anywhere that distinguishes "disabled" from "enabled" for a user working through the YAML, and the workflow keeps running.
Asks (any one would resolve it)
- Honour it — have workflow create/update apply the definition's
enabled to the column, so the field means what it says.
- Reject it — fail the update with "use
set_workflow_enabled / the UI toggle; enabled in the definition is not applied", so the user learns at write time.
- At minimum, warn on accepting a definition whose
enabled disagrees with the stored column.
Option 1 is the least surprising. Options 2 and 3 at least make the gap visible.
Workaround
Park the cron (e.g. cron: "0 9 1 1 *") — the trigger is read from the definition, so that genuinely stops scheduled firing. Or call set_workflow_enabled directly.
Summary
A workflow definition's
enabledfield parses, validates, round-trips through the relay, and does nothing. The scheduler reads theenabledtable column, which the definition never writes. A user who "disabled" a workflow by editing its YAML still has it running on schedule, and every surface they can check says it is disabled.This fails in the direction users care about: silently keeping something running that they believe they turned off.
Where
enabledis a column (:290, in the INSERT column list alongsidedefinition), and the only writer isset_workflow_enabled()(:684), reachable through its own API. Thedefinitionblob — where the YAMLenabled:lives — is never consulted by the scheduler query. Verified present at HEAD.Reproduction
scheduletrigger.buzz workflows updateit with a definition whose top level containsenabled: false.{"accepted":true}) — no warning, no validation error.enabledis stillt.Observed on a self-hosted relay at v0.5.3.
Why this is worse than a no-op field
The field looks authoritative. It is at the top level of the definition next to
name,description, andtrigger, all of which are honoured. It survives a round-trip, soworkflows getechoes backenabled: false— which reads as confirmation that the setting took effect. There is no diagnostic anywhere that distinguishes "disabled" from "enabled" for a user working through the YAML, and the workflow keeps running.Asks (any one would resolve it)
enabledto the column, so the field means what it says.set_workflow_enabled/ the UI toggle;enabledin the definition is not applied", so the user learns at write time.enableddisagrees with the stored column.Option 1 is the least surprising. Options 2 and 3 at least make the gap visible.
Workaround
Park the cron (e.g.
cron: "0 9 1 1 *") — the trigger is read from the definition, so that genuinely stops scheduled firing. Or callset_workflow_enableddirectly.