openclaw - 💡(How to fix) Fix [Bug]: Isolated/delegated sessions reject `message` and `sessions_send` to a configured DM channel ("session visibility"), breaking notify-on-completion hooks

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…

When an agent runs in any context other than a live channel-bound session — e.g. a cron job, a sessions_spawn subagent, or any other isolated lane — calling the message (action=send) or sessions_send tool to the agent's own configured DM channel is rejected with a "session visibility" / channel-not-bound error. The same destination is reachable from the agent's main session without issue, so this is purely a session-scope tool-binding gap, not a channel-adapter or auth problem.

This blocks the common "background task completes → notify the operator" pattern: cron jobs that should post a status line, subagents that finish and want to surface results, any hook that expects to write back through the agent's DM channel from outside the main session.

Error Message

When an agent runs in any context other than a live channel-bound session — e.g. a cron job, a sessions_spawn subagent, or any other isolated lane — calling the message (action=send) or sessions_send tool to the agent's own configured DM channel is rejected with a "session visibility" / channel-not-bound error. The same destination is reachable from the agent's main session without issue, so this is purely a session-scope tool-binding gap, not a channel-adapter or auth problem. 3. The call is rejected with a session-visibility / channel-not-bound error, even though the agent's identity and channel config are unchanged. message and sessions_send should resolve the destination from the agent's persistent channel bindings as the primary source — the agent owns the bot account and the DM pairing, not the session. An isolated lane inheriting that agent identity should be able to reach the same DM, or at minimum receive a clear preflight error naming which binding is missing. These tools are silently scoped to the calling session's bound channels only. Isolated lanes get a generic visibility/reject error. The only path that actually works from those contexts is enqueueing a one-shot cron job whose delivery.announce route hits the channel — brittle and adds seconds of latency for what should be a single in-process send.

  • Either way, surface a preflight error like channel "telegram" not bound for this session; agent has binding X — enable cross-session sends or use channel announce route so the agent can act on it instead of hitting a generic visibility reject.

Root Cause

When an agent runs in any context other than a live channel-bound session — e.g. a cron job, a sessions_spawn subagent, or any other isolated lane — calling the message (action=send) or sessions_send tool to the agent's own configured DM channel is rejected with a "session visibility" / channel-not-bound error. The same destination is reachable from the agent's main session without issue, so this is purely a session-scope tool-binding gap, not a channel-adapter or auth problem.

This blocks the common "background task completes → notify the operator" pattern: cron jobs that should post a status line, subagents that finish and want to surface results, any hook that expects to write back through the agent's DM channel from outside the main session.

Fix Action

Fix / Workaround

Agents that reason about this fall into a predictable pattern: try message / sessions_send, hit the visibility reject, then either give up silently or queue a throwaway cron entry as the workaround.

Workarounds (both brittle)

RAW_BUFFERClick to expand / collapse

Summary

When an agent runs in any context other than a live channel-bound session — e.g. a cron job, a sessions_spawn subagent, or any other isolated lane — calling the message (action=send) or sessions_send tool to the agent's own configured DM channel is rejected with a "session visibility" / channel-not-bound error. The same destination is reachable from the agent's main session without issue, so this is purely a session-scope tool-binding gap, not a channel-adapter or auth problem.

This blocks the common "background task completes → notify the operator" pattern: cron jobs that should post a status line, subagents that finish and want to surface results, any hook that expects to write back through the agent's DM channel from outside the main session.

Repro

Minimal shape (Telegram bot in our setup, same shape on any channel adapter that supports DMs):

  1. Configure an agent with a Telegram bot account and an approved DM pairing. From the agent's main session, message(action="send", channel="telegram", to=<chatId>) succeeds.
  2. From any of the following, have the same agent invoke the same call to the same <chatId>:
    • A cron job added with openclaw cron add ... --session isolated (also reproduces with --session main).
    • A sessions_spawn-launched subagent that has message in its tool allow-list.
  3. The call is rejected with a session-visibility / channel-not-bound error, even though the agent's identity and channel config are unchanged.

Expected

message and sessions_send should resolve the destination from the agent's persistent channel bindings as the primary source — the agent owns the bot account and the DM pairing, not the session. An isolated lane inheriting that agent identity should be able to reach the same DM, or at minimum receive a clear preflight error naming which binding is missing.

Actual

These tools are silently scoped to the calling session's bound channels only. Isolated lanes get a generic visibility/reject error. The only path that actually works from those contexts is enqueueing a one-shot cron job whose delivery.announce route hits the channel — brittle and adds seconds of latency for what should be a single in-process send.

Agents that reason about this fall into a predictable pattern: try message / sessions_send, hit the visibility reject, then either give up silently or queue a throwaway cron entry as the workaround.

Workarounds (both brittle)

  1. Bypass the tool entirely: shell out from exec to curl https://api.telegram.org/bot${TOKEN}/sendMessage ... using the bot token from env. Works in any session shape, but every channel adapter needs its own bypass script, the operator owns token resolution, and the agent loses OpenClaw's rate-limit / queueing / idempotency.
  2. Per-call cron enqueue: have the agent add a one-shot cron entry whose only purpose is to announce through the channel route. Works but pollutes cron list with throwaway entries and adds noticeable latency.

Relevant context

docs/concepts/session.md describes per-session channel scopes but doesn't call out that isolated/cron lanes inherit none of the agent's channel bindings for outbound sends. Recent changelog entries do adjacent work but don't address this directly — e.g. cron lane isolation in 2026.5.19, tools.message.crossContext per-agent overrides in 2026.5.12 — so this looks like a real gap, not a regression.

Environment

  • OpenClaw 2026.5.19 (image ghcr.io/openclaw/openclaw:latest, revision ca3c3fca432c2b7d3c9e7b92d7dae3d332389b03)
  • Deployed via Docker, macOS host on Apple Silicon
  • Single agent, Telegram bot adapter, DM peer pairing approved and working from the main session
  • Same pattern observed continuously across 2026.4.272026.5.19

Suggested fix direction (not prescriptive)

  • Resolve message / sessions_send destinations against the agent's persistent channel bindings first, falling back to session-scope only when the agent has no persistent binding for that channel.
  • Or expose an explicit per-agent opt-in like tools.message.allowOutOfSessionChannels: ["telegram", ...] for operators who knowingly want isolated lanes to share the agent's DM bindings.
  • Either way, surface a preflight error like channel "telegram" not bound for this session; agent has binding X — enable cross-session sends or use channel announce route so the agent can act on it instead of hitting a generic visibility reject.

Happy to follow up with a minimal repro repo if useful.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING