openclaw - ✅(Solved) Fix [Bug]: Cron delivery ignores explicit delivery.channel when sessionTarget=isolated [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#61414Fetched 2026-04-08 02:58:54
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Participants
Timeline (top)
cross-referenced ×1

Cron jobs with explicit delivery.channel setting (e.g., "webchat") deliver to wrong channel when sessionTarget="isolated". The configured channel is ignored and delivery falls back to "last", which resolved to an active iMessage session instead of the configured webchat channel.


Root Cause

Root cause identified:

Fix Action

Fixed

PR fix notes

PR #61431: test(cron): lock explicit isolated delivery.channel routing

Description (problem / solution / changelog)

Summary

  • Problem: #61414 reports isolated cron agent turns ignoring an explicit delivery.channel and falling back to last.
  • Why it matters: if that behavior regresses, cron output can land on the wrong surface.
  • What changed: add regression coverage for the exact isolated agentTurn + explicit delivery.channel case in both the delivery planner and job creation path.
  • What did NOT change (scope boundary): no runtime delivery logic changed in this PR; current main already preserves explicit channels in resolveCronDeliveryPlan().

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #61414
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: the user-visible report in #61414 describes older release behavior, but current main already preserves explicit delivery.channel when job.delivery is present. The missing piece on main was regression coverage for that exact route.
  • Missing detection / guardrail: there was no targeted test proving isolated agentTurn jobs keep an explicit channel like webchat instead of falling back to last.
  • Contributing context (if known): the issue cited compiled 2026.4.1 output; current source under src/cron/delivery-plan.ts already takes the explicit-delivery branch before the implicit isolated fallback.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/cron/delivery.test.ts
    • src/cron/service.jobs.test.ts
  • Scenario the test should lock in: isolated agentTurn jobs with delivery: { mode: "announce", channel: "webchat" } keep webchat through both job creation and delivery-plan resolution.
  • Why this is the smallest reliable guardrail: the reported behavior is fully determined by the cron job creation + delivery-planning helpers, so focused tests on those helpers catch the regression without a larger end-to-end harness.
  • Existing test that already covers this (if any): none specific to explicit delivery.channel on isolated jobs.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

None on current main; this locks existing behavior so it does not regress.

Diagram (if applicable)

Before:
[isolated cron agentTurn + delivery.channel=webchat] -> [behavior depended on helper correctness]

After:
[isolated cron agentTurn + delivery.channel=webchat] -> [targeted tests assert webchat survives] -> [future regressions fail fast]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / Vitest
  • Model/provider: N/A
  • Integration/channel (if any): cron delivery planning
  • Relevant config (redacted): isolated agentTurn with delivery.channel: "webchat"

Steps

  1. Create an isolated cron agentTurn with delivery: { mode: "announce", channel: "webchat" }.
  2. Resolve the delivery plan and create the job.
  3. Assert both helpers preserve webchat instead of falling back to last.

Expected

  • Explicit delivery.channel stays webchat.

Actual

  • Current main already behaves that way; these tests now lock it in.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • resolveCronDeliveryPlan() preserves delivery.channel="webchat" for isolated agentTurn jobs.
    • createJob() preserves explicit delivery config instead of collapsing it to implicit announce defaults.
  • Edge cases checked:
    • implicit isolated delivery still defaults to last
    • explicit delivery still works when mode is omitted or changed elsewhere in existing tests
  • What you did not verify:
    • I did not run a full end-to-end gateway cron delivery scenario because the helper-level tests fully cover the reported routing decision path.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: this is test-only, so if the real issue was in a release-only compiled artifact or another downstream path, this PR will not address that separately.
    • Mitigation: the PR body is explicit about the current main behavior and scopes the change to regression coverage for the planner/create path implicated by #61414.

Changed files

  • src/cron/delivery.test.ts (modified, +12/-0)
  • src/cron/service.jobs.test.ts (modified, +5/-2)

Code Example

{
  "name": "workspace-cleanup",
  "schedule": { "kind": "every", "everyMs": 86400000 },
  "sessionTarget": "isolated",
  "payload": {
    "kind": "agentTurn",
    "message": "Scan workspace and report orphan files..."
  },
  "delivery": {
    "mode": "announce",
    "channel": "webchat"
  }
}

---

{
  "delivery": { "mode": "announce", "channel": "webchat" },
  "sessionTarget": "isolated",
  "payload": { "kind": "agentTurn", ... }
}

---

const resolvedMode = job.payload.kind === "agentTurn" && 
  (job.sessionTarget === "isolated" || job.sessionTarget === "current" || job.sessionTarget.startsWith("session:")) 
  ? "announce" : "none";

return {
  mode: resolvedMode,
  channel: resolvedMode === "announce" ? "last" : void 0,  // BUG: ignores delivery.channel
  ...
}

---

channel: resolvedMode === "announce" ? (delivery?.channel ?? "last") : void 0,
RAW_BUFFERClick to expand / collapse

Bug Report for OpenClaw

Bug type: Behavior bug (incorrect output/state without crash)

Beta release blocker: No


Summary

Cron jobs with explicit delivery.channel setting (e.g., "webchat") deliver to wrong channel when sessionTarget="isolated". The configured channel is ignored and delivery falls back to "last", which resolved to an active iMessage session instead of the configured webchat channel.


Steps to reproduce

  1. Create a cron job with explicit delivery config:
{
  "name": "workspace-cleanup",
  "schedule": { "kind": "every", "everyMs": 86400000 },
  "sessionTarget": "isolated",
  "payload": {
    "kind": "agentTurn",
    "message": "Scan workspace and report orphan files..."
  },
  "delivery": {
    "mode": "announce",
    "channel": "webchat"
  }
}
  1. Have an active iMessage session with any contact

  2. Let the cron job run at its scheduled time

  3. Observe the delivery goes to iMessage instead of webchat


Expected behavior

The cron job output should be delivered to webchat as explicitly configured in delivery.channel.


Actual behavior

The output was delivered to iMessage (agent:main:imessage:direct:<redacted>). The configured delivery.channel was ignored, and the system fell back to resolving "last" from session store, which had an active iMessage session.


Environment

OpenClaw version: 2026.4.1

Operating system: macOS 15.3

Install method: npm global

Model: ollama/kimi-k2.5:cloud

Provider / routing chain: openclaw → ollama


Logs, screenshots, and evidence

Cron run record showing delivery.channel: "webchat" in config but delivery to iMessage session:

{
  "delivery": { "mode": "announce", "channel": "webchat" },
  "sessionTarget": "isolated",
  "payload": { "kind": "agentTurn", ... }
}

Session key where delivery occurred: agent:main:imessage:direct:<redacted>


Impact and severity

  • Affected: Users with cron jobs configured for specific channels (webchat) who also have iMessage enabled
  • Severity: High (privacy risk - messages sent to unintended recipients)
  • Frequency: Always when sessionTarget="isolated" and delivery.channel is explicitly set to a non-default channel
  • Consequence: Sensitive cron output delivered to wrong recipients; loss of trust in automated task delivery

Additional information

Root cause identified:

In src/cron/delivery.ts (compiled to gateway-cli-CWpalJNJ.js lines 3936-3939), the resolveCronDeliveryPlan function incorrectly overrides the explicit delivery.channel setting:

const resolvedMode = job.payload.kind === "agentTurn" && 
  (job.sessionTarget === "isolated" || job.sessionTarget === "current" || job.sessionTarget.startsWith("session:")) 
  ? "announce" : "none";

return {
  mode: resolvedMode,
  channel: resolvedMode === "announce" ? "last" : void 0,  // BUG: ignores delivery.channel
  ...
}

When sessionTarget="isolated" and payload.kind="agentTurn", the code unconditionally sets channel: "last", ignoring any explicitly configured delivery.channel.

Suggested fix:

channel: resolvedMode === "announce" ? (delivery?.channel ?? "last") : void 0,

This respects the explicit channel when provided, only falling back to "last" when no channel is configured.

extent analysis

TL;DR

The most likely fix for the issue is to update the resolveCronDeliveryPlan function to respect the explicit delivery.channel setting when sessionTarget="isolated".

Guidance

  • Review the src/cron/delivery.ts file and verify that the resolveCronDeliveryPlan function is overriding the explicit delivery.channel setting.
  • Update the channel assignment in the resolveCronDeliveryPlan function to use the suggested fix: channel: resolvedMode === "announce" ? (delivery?.channel ?? "last") : void 0.
  • Test the updated function with a cron job that has an explicit delivery.channel setting and sessionTarget="isolated" to ensure that the delivery is sent to the correct channel.
  • Consider adding additional logging or debugging statements to verify that the delivery.channel setting is being respected.

Example

const resolvedMode = job.payload.kind === "agentTurn" && 
  (job.sessionTarget === "isolated" || job.sessionTarget === "current" || job.sessionTarget.startsWith("session:")) 
  ? "announce" : "none";

return {
  mode: resolvedMode,
  channel: resolvedMode === "announce" ? (delivery?.channel ?? "last") : void 0,
  ...
}

Notes

  • The suggested fix assumes that the delivery object has a channel property that contains the explicit channel setting.
  • The fix may need to be adapted or modified to fit the specific requirements of the OpenClaw application.

Recommendation

Apply the suggested fix to the resolveCronDeliveryPlan function to respect the explicit delivery.channel setting when sessionTarget="isolated". This should resolve the issue and prevent sensitive cron output from being delivered to the wrong recipients.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The cron job output should be delivered to webchat as explicitly configured in delivery.channel.


Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: Cron delivery ignores explicit delivery.channel when sessionTarget=isolated [1 pull requests, 1 participants]