From 3a72c8aa3979ed0c438a880122969e0b4c97b5b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Sun, 19 Apr 2026 18:21:24 -0400 Subject: [PATCH] Skip cleanly when channel-target resolution fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `dispatchAgentMessage` requires a `channelTargetId` for `department` and `project` channels, but the default "Notify department on task completion" rule is agent-agnostic — it has to derive the target at fire time. Single-agent companies and any sender without a `department` produced a WARN every run completion that read like a real failure and made the log tail look like the system was broken. The action handler now treats "channel needs a target and we couldn't resolve one" as "no recipient available" and skips with an INFO line. The dispatcher is no longer asked to validate an input we already know is incomplete, and the operator stops seeing `CHANNEL_TARGET_REQUIRED` rejections during routine completions. --- src/main/automation/automation-actions.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/automation/automation-actions.ts b/src/main/automation/automation-actions.ts index 8c23fa36..1cc28061 100644 --- a/src/main/automation/automation-actions.ts +++ b/src/main/automation/automation-actions.ts @@ -154,6 +154,21 @@ export function executeAutomationAction( channelTargetId = null; } } + // `dispatchAgentMessage` rejects department / project messages + // that arrive without a channel target. The default rule + // "Notify department on task completion" is agent-agnostic + // (the operator may not have a department per agent), so a + // single-person company or any agent without a department + // routinely lands here. Treat the missing target as "no + // recipients available" and skip — the previous behaviour + // logged a noisy WARN that looked like a real failure. + const channelNeedsTarget = channel === "department" || channel === "project"; + if (channelNeedsTarget && !channelTargetId) { + logger.info( + `[automation] Skipping rule "${rule.name}" — no ${channel} channel target available for sender ${fromAgentId}`, + ); + break; + } const dispatchResult = dispatchAgentMessage( { db, emitEvent, publishDomainChanged, wakeAgentIfPossible }, {