block / block/buzz

Workflow send_message cannot target a different channel; runs fail silently

Open
#2,979 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

## Summary

A workflow whose `send_message` step targets a **different channel** than the one the workflow is bound to always fails. The run is created and accepted, then dies at the first step with no user-visible error. From the outside it looks like "workflows silently do nothing."

## Repro

1. Create a workflow in channel A:

```yaml
name: Recycle to Kaizen
trigger:
on: reaction_added
emoji: "♻️"
steps:
- id: post_candidate
action: send_message
channel:
text: "## Flagged for Kaizen"
enabled: true
```

2. `buzz workflows trigger --workflow ` → `{"accepted": true, "run_id": "..."}`
3. Nothing is ever posted to channel B, and nothing is posted to channel A either.

## Cause

`resolve_send_message_channel` in `crates/buzz-workflow/src/executor.rs:468` rejects any `channel:` override that differs from the workflow's own `channel_id`:

```rust
if override_channel_id != workflow_channel_id {
return Err(WorkflowError::InvalidDefinition(format!(
"SendMessage: channel override must match the workflow channel ({workflow_channel_id})"
)));
}
```

Since every channel-created workflow has `workflow_channel_id = Some(...)`, the `channel:` field is effectively **write-only** — it can only ever name the channel it already posts to. Cross-channel routing is impossible.

## Why this is worse than a missing feature

The `channel:` key is accepted at create time by the schema and by Desktop's workflow form. There is no validation error, no warning, and no run-history surface (see the related issue on run visibility), so the failure is invisible at every layer. Three separate debugging sessions on my side concluded "workflow steps don't execute at all" before reading the source.

## Requested

Either:

- **(preferred)** allow `send_message` to target any channel the workflow **owner** is a member of, authorizing on owner membership rather than on workflow binding; or
- reject the workflow at **create/update time** with a clear error if `channel:` differs from the workflow channel, so the failure is visible immediately instead of at run time.

Cross-channel routing is the core of most useful reaction workflows — "react with an emoji, file it into the triage channel." Without it `reaction_added` can only echo into the channel it fired in.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.