openclaw - ✅(Solved) Fix sessions_spawn rejects non-delivery channels (heartbeat, webhook, cron) [2 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#73237Fetched 2026-04-29 06:21:58
View on GitHub
Comments
0
Participants
1
Timeline
8
Reactions
0
Author
Participants
Timeline (top)
referenced ×5cross-referenced ×2closed ×1

Root Cause

This happens because isGatewayMessageChannel() only includes deliverable channel IDs + registered plugins + webchat as the internal channel. Heartbeat/cron/webhook sessions are not represented there.

Fix Action

Workaround

Wait for a live invocation (Telegram/webchat) to spawn subagents instead of relying on heartbeat ticks.

PR fix notes

PR #73263: fix(gateway): allow internal agent channel hints

Description (problem / solution / changelog)

Summary

  • Accept internal non-delivery channel hints (cron, heartbeat, webhook) during agent request validation.
  • Normalize those internal hints out of delivery/session routing so they do not behave like deliverable channels.
  • Keep unknown external channel rejection unchanged.
  • Add a gateway-server regression test for those internal hints.

Closes #73237

Testing

  • pnpm exec oxfmt --check --threads=1 src/gateway/server-methods/agent.ts src/gateway/server.agent.gateway-server-agent-b.test.ts
  • pnpm test src/gateway/server.agent.gateway-server-agent-b.test.ts -t 'agent accepts internal non-delivery channel hints'
  • pnpm lint:core

AI-assisted disclosure

AI-assisted: yes. I understand the change; internal source channels are accepted as provenance but intentionally ignored for delivery routing.

Changed files

  • src/gateway/server-methods/agent.ts (modified, +18/-6)
  • src/gateway/server.agent.gateway-server-agent-b.test.ts (modified, +13/-0)

PR #73282: fix(gateway): accept heartbeat/cron/webhook channel hints in agent params (#73237)

Description (problem / solution / changelog)

Summary

Fixes #73237. agentHandlers.agent rejected request.channel / request.replyChannel values like heartbeat, cron, and webhook with invalid agent params: unknown channel: ..., blocking sessions_spawn calls from agent runs triggered by non-delivery sources. The validation only accepted isGatewayMessageChannel(value) (deliverable channels + plugins + webchat).

This PR adds an explicit INTERNAL_NON_DELIVERY_CHANNELS set (heartbeat, cron, webhook) and a typed isInternalNonDeliveryChannel predicate, then composes it into the channel-hint check in src/gateway/server-methods/agent.ts so internal-source parent runs can spawn subagents without hitting validation.

Changes

FileWhat
src/utils/message-channel-constants.tsnew: INTERNAL_NON_DELIVERY_CHANNELS, InternalNonDeliveryChannel, isInternalNonDeliveryChannel
src/utils/message-channel.tsre-export the new symbols from the constants module
src/utils/message-channel.test.tsunit test for isInternalNonDeliveryChannel (members accepted, others rejected, no implicit case-folding)
src/gateway/server-methods/agent.tsbroaden isKnownGatewayChannel to also accept isInternalNonDeliveryChannel
src/gateway/server-methods/agent.test.tsparameterised acceptance test for heartbeat/cron/webhook + a regression test that genuine unknown channels still 400
 5 files changed, 86 insertions(+), 1 deletion(-)

Tests

  • pnpm test src/utils/message-channel.test.ts — 4 pass (1 new)
  • pnpm test src/gateway/server-methods/agent.test.ts — 64 pass (4 new)
  • pnpm exec oxfmt --check — clean
  • pnpm exec oxlint — 0 warnings, 0 errors
  • pnpm tsgo — clean

Context

Closes #73237.

Subagent spawning is intentionally channel-agnostic — the parent channel identity isn't relevant to child session creation. The reporter offered two fix options; this implements the second (expand the accepted-channel set with an explicit, named constant) because it keeps the existing validation a single boolean predicate and makes the new accepted values searchable / testable as a typed union, rather than scattering "skip validation for these strings" branches.

isGatewayMessageChannel is intentionally unchanged: the new constants are a separate, narrower category (non-delivery sources), not deliverable channels — anything that calls isGatewayMessageChannel to decide where to send output keeps the same behavior.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/gateway/server-methods/agent.test.ts (modified, +54/-0)
  • src/gateway/server-methods/agent.ts (modified, +5/-1)
  • src/utils/message-channel-constants.ts (modified, +13/-0)
  • src/utils/message-channel.test.ts (modified, +12/-0)
  • src/utils/message-channel.ts (modified, +3/-0)

Code Example

invalid agent params: unknown channel: heartbeat
RAW_BUFFERClick to expand / collapse

Bug

When an agent running on a non-delivery channel (e.g. heartbeat, cron, webhook) calls sessions_spawn, the server-side agent param validation rejects the request:

invalid agent params: unknown channel: heartbeat

This happens because isGatewayMessageChannel() only includes deliverable channel IDs + registered plugins + webchat as the internal channel. Heartbeat/cron/webhook sessions are not represented there.

Location

server-methods.ts — agent param validation around the channel hint check: ``` const isKnownGatewayChannel = (value) => isGatewayMessageChannel(value); const channelHints = [request.channel, request.replyChannel]... for (const rawChannel of channelHints) { if (normalized && normalized !== "last" && !isKnownGatewayChannel(normalized)) { respond(false, ..., invalid agent params: unknown channel: ${normalized}); } } ```

Suggested fix

Either:

  1. Skip channel validation when the channel is a known internal/non-delivery source (heartbeat, cron, webhook)
  2. Add these internal channels to isGatewayMessageChannel / expand INTERNAL_MESSAGE_CHANNEL

Subagent spawning should be channel-agnostic — the parent channel identity is not relevant to child session creation.

Workaround

Wait for a live invocation (Telegram/webchat) to spawn subagents instead of relying on heartbeat ticks.

Environment

OpenClaw 2026.4.26 (be8c246)

extent analysis

TL;DR

Modify the isKnownGatewayChannel function to either skip validation for internal channels like heartbeat, cron, and webhook, or add these channels to the isGatewayMessageChannel check.

Guidance

  • Identify the channels that are considered internal or non-delivery sources (heartbeat, cron, webhook) and determine the best approach to handle them, either by skipping validation or adding them to the known channels list.
  • Review the isGatewayMessageChannel function to understand how it currently determines valid channels and consider expanding it to include internal channels if necessary.
  • Test the modified validation logic with different channel types to ensure it correctly handles both delivery and non-delivery channels.
  • Consider the workaround of waiting for a live invocation to spawn subagents if modifying the validation logic is not feasible in the short term.

Example

const isKnownGatewayChannel = (value) => {
  // Add internal channels to the list of known channels
  const internalChannels = ['heartbeat', 'cron', 'webhook'];
  return isGatewayMessageChannel(value) || internalChannels.includes(value);
};

Notes

The suggested fix requires careful consideration of the implications of modifying the channel validation logic, as it may have security or functionality implications. The workaround may have performance or usability implications and should be evaluated accordingly.

Recommendation

Apply the workaround of waiting for a live invocation to spawn subagents, as it does not require modifying the existing validation logic and can be implemented quickly. This approach allows for a temporary solution while a more permanent fix is developed and tested.

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

openclaw - ✅(Solved) Fix sessions_spawn rejects non-delivery channels (heartbeat, webhook, cron) [2 pull requests, 1 participants]