-
-
Notifications
You must be signed in to change notification settings - Fork 52.6k
Description
Summary
When a cron job with delivery.mode: "announce" fires while the main session is actively replying inside a Slack thread, the delivery inherits lastThreadId from the session and sends the cron output into the active thread instead of the top-level DM.
This causes unrelated content (research reports, reminders, proactive cron output) to appear inside whichever thread happens to be active at the moment — confusing and disruptive.
Root cause
resolveSessionDeliveryTarget() in targets.ts unconditionally inherits lastThreadId when the channel matches:
const threadId = channel && channel === lastChannel ? lastThreadId : void 0;
// ...
const resolvedThreadId = explicitThreadId ?? threadId;The heartbeat/cron delivery path calls this via resolveHeartbeatDeliveryTarget() with mode: "heartbeat", but resolveSessionDeliveryTarget does not use this mode to suppress lastThreadId fallback.
Steps to reproduce
- Configure a cron job with
delivery.mode: "announce",delivery.channel: "slack",delivery.to: "user:<userId>" - Start a conversation in a Slack thread (reply to any message)
- Wait for the cron job to fire while the thread conversation is active
- Observe: cron output appears inside the active thread instead of top-level DM
Expected behavior
Cron announce delivery should send to the top-level DM channel, ignoring any active lastThreadId from the session. Thread targeting should only happen when explicitly configured (e.g., the proposed C12345:thread:TS syntax from #19903).
Suggested fix
In resolveSessionDeliveryTarget(), skip lastThreadId fallback when mode === "heartbeat":
const threadId = (params.mode !== "heartbeat" && channel && channel === lastChannel)
? lastThreadId
: void 0;This is a one-line change. The function already receives the mode parameter — it just needs to use it.
Environment
- OpenClaw version: 2026.2.23 (also present in 2026.2.22-2)
- Channel: Slack (Socket Mode)
- Cron job config:
sessionTarget: "isolated",delivery.mode: "announce",delivery.to: "user:<id>"
Related
- [Feature]: Support Slack thread targeting for cron and heartbeat delivery #19903 — Feature request for explicit Slack thread targeting in cron/heartbeat delivery
- Telegram DM: lastThreadId cached from incoming messages causes reply delivery failures #13566 — Similar
lastThreadIdcaching issue on Telegram DMs
AI-Assisted Disclosure
This issue was filed by an AI assistant (Claude, via OpenClaw). The root cause analysis was performed by reading the minified source in dist/reply-*.js and tracing the delivery flow through resolveHeartbeatDeliveryTarget → resolveSessionDeliveryTarget. The author (human operator) understands the issue and has experienced it repeatedly in production.