Skip to content

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

Merged
steipete merged 4 commits into
openclaw:mainfrom
KeWang0622:fix/sessions-spawn-internal-channels
Apr 28, 2026
Merged

fix(gateway): accept heartbeat/cron/webhook channel hints in agent params (#73237)#73282
steipete merged 4 commits into
openclaw:mainfrom
KeWang0622:fix/sessions-spawn-internal-channels

Conversation

@KeWang0622

Copy link
Copy Markdown
Contributor

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

File What
src/utils/message-channel-constants.ts new: INTERNAL_NON_DELIVERY_CHANNELS, InternalNonDeliveryChannel, isInternalNonDeliveryChannel
src/utils/message-channel.ts re-export the new symbols from the constants module
src/utils/message-channel.test.ts unit test for isInternalNonDeliveryChannel (members accepted, others rejected, no implicit case-folding)
src/gateway/server-methods/agent.ts broaden isKnownGatewayChannel to also accept isInternalNonDeliveryChannel
src/gateway/server-methods/agent.test.ts parameterised 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.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S labels Apr 28, 2026
@greptile-apps

greptile-apps Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a validation bug in agentHandlers.agent where channel/replyChannel values of heartbeat, cron, or webhook caused a 400 rejection when spawning subagents from non-delivery-triggered parent runs. The fix introduces a typed INTERNAL_NON_DELIVERY_CHANNELS constant and isInternalNonDeliveryChannel predicate in message-channel-constants.ts, re-exports them from the barrel, and widens isKnownGatewayChannel in agent.ts to accept these values alongside gateway message channels. The changes are minimal, well-scoped, and covered by both unit and integration tests.

Confidence Score: 5/5

This PR is safe to merge — the change is a narrow, additive fix with clear tests and no impact on existing delivery-channel logic.

The fix is minimal and additive: a new constant, a typed predicate, and a single || in the validation guard. isGatewayMessageChannel is unchanged, so existing delivery-channel paths are unaffected. The normalization pipeline (normalizeMessageChannel lowercases before the predicate is called) is consistent with the new constants being lowercase, and the unit tests explicitly cover the direct-predicate no-case-folding behavior. No security or data-integrity concerns identified.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(gateway): accept heartbeat/cron/webh..." | Re-trigger Greptile

@KeWang0622

Copy link
Copy Markdown
Contributor Author

The two failing checks (checks-node-core-fast-support and checks-node-core) are pre-existing on main and unrelated to this PR. The failing tests are:

  • test/scripts/plugin-boundary-report.test.tsexpected 'private-package-core-integrated' to be 'private-core-bridge'
  • src/memory-host-sdk/host/embeddings.test.tsCannot find package 'node-llama-cpp' (5 tests)

Same job names, same failures, on main run 25034307683 at commit 996818e6 ("fix: follow up main ci failures") — i.e. main has been red on these two jobs since before this branch existed. This PR only touches src/utils/message-channel*, src/gateway/server-methods/agent.ts, and their colocated tests; none of those areas involve plugin-boundary-report or node-llama-cpp embeddings.

Per CONTRIBUTING.md:

"Do not submit test or CI-config fixes for failures already red on main CI."

Happy to rebase once main is green if that helps the merge queue.

@KeWang0622

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (27e31305) — main went green at 05:36 with 252cc7ec test: fix unit-fast config assertion + 27e31305 test(gateway): keep session event suite minimal, which fix the plugin-boundary-report and node-llama-cpp shards I described above. CI should now run clean.

No code changes — same 5-file diff (+86/-1).

@steipete steipete force-pushed the fix/sessions-spawn-internal-channels branch from 9af755a to f07489e Compare April 28, 2026 06:00
@clawsweeper

clawsweeper Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Codex automated review: keeping this open.

Keep this PR open. Current main still rejects heartbeat, cron, and webhook channel hints in the gateway agent handler, while the linked bug remains open. The PR is a focused implementation candidate: it widens validation only for named internal non-delivery hints, keeps unknown channels fail-closed, and adds regression coverage for both channel and replyChannel.

Best possible solution:

Keep this PR open and review or land it, or land an equivalent main-branch fix. The implementation should accept heartbeat, cron, and webhook only as internal non-delivery agent channel hints, preserve isGatewayMessageChannel semantics for actual delivery decisions, and keep regression tests for channel and replyChannel acceptance plus genuine unknown-channel rejection.

What I checked:

  • Current main still validates only gateway message channels: At current main, agent param validation defines isKnownGatewayChannel as exactly isGatewayMessageChannel(value), then rejects any normalized channel or replyChannel hint that is not last and fails that predicate with invalid agent params: unknown channel. (src/gateway/server-methods/agent.ts:543, c3c8d66acf95)
  • Current gateway channel set excludes the requested non-delivery sources: The current channel constants define only webchat as the internal message channel, and listGatewayMessageChannels is deliverable channels plus that single internal channel. There is no INTERNAL_NON_DELIVERY_CHANNELS equivalent on main. (src/utils/message-channel-normalize.ts:35, c3c8d66acf95)
  • Subagent spawn can still forward the requester channel hint: The sessions_spawn path calls the gateway agent method and passes channel: childSessionOrigin?.channel into the child agent call, so a non-delivery parent origin can still hit the gateway channel validation before the child run starts. (src/agents/subagent-spawn.ts:1057, c3c8d66acf95)
  • Current tests cover rejection, not acceptance: Main has tests that reject unknown channel/replyChannel hints, but no acceptance coverage for heartbeat, cron, or webhook. A grep for the linked bug and the proposed non-delivery predicate found no implementation or changelog entry on current main. (src/gateway/server.agent.gateway-server-agent-a.test.ts:271, c3c8d66acf95)
  • Linked bug is still open and matches this PR: The live issue report for sessions_spawn rejects non-delivery channels (heartbeat, webhook, cron) #73237 says sessions_spawn from heartbeat, cron, or webhook parents fails with invalid agent params: unknown channel, and it remains open.
  • PR diff is a narrow additive fix with tests: The final PR file list adds INTERNAL_NON_DELIVERY_CHANNELS and isInternalNonDeliveryChannel, composes that predicate into gateway agent validation, adds channel and replyChannel acceptance tests plus unknown-hint rejection tests, and adds a changelog entry. (src/gateway/server-methods/agent.ts:541, ec288e329272)

Remaining risk / open question:

Codex Review notes: model gpt-5.5, reasoning high; reviewed against c3c8d66acf95.

@steipete steipete force-pushed the fix/sessions-spawn-internal-channels branch from 5757de8 to ec288e3 Compare April 28, 2026 06:21
@steipete steipete force-pushed the fix/sessions-spawn-internal-channels branch from 453ed6a to 543cf25 Compare April 28, 2026 06:29
@steipete steipete merged commit a253660 into openclaw:main Apr 28, 2026
67 checks passed
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
…rams (openclaw#73237) (openclaw#73282)

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

* test(gateway): cover internal reply channel hints

* test(openai): include codex mini catalog expectation

* test(openai): follow codex catalog fixture split

---------

Co-authored-by: Ke Wang <ke@pika.art>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…rams (openclaw#73237) (openclaw#73282)

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

* test(gateway): cover internal reply channel hints

* test(openai): include codex mini catalog expectation

* test(openai): follow codex catalog fixture split

---------

Co-authored-by: Ke Wang <ke@pika.art>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
globalcaos pushed a commit to globalcaos/tinkerclaw that referenced this pull request May 13, 2026
…rams (openclaw#73237) (openclaw#73282)

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

* test(gateway): cover internal reply channel hints

* test(openai): include codex mini catalog expectation

* test(openai): follow codex catalog fixture split

---------

Co-authored-by: Ke Wang <ke@pika.art>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
…rams (openclaw#73237) (openclaw#73282)

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

* test(gateway): cover internal reply channel hints

* test(openai): include codex mini catalog expectation

* test(openai): follow codex catalog fixture split

---------

Co-authored-by: Ke Wang <ke@pika.art>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
…rams (openclaw#73237) (openclaw#73282)

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

* test(gateway): cover internal reply channel hints

* test(openai): include codex mini catalog expectation

* test(openai): follow codex catalog fixture split

---------

Co-authored-by: Ke Wang <ke@pika.art>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
…rams (openclaw#73237) (openclaw#73282)

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

* test(gateway): cover internal reply channel hints

* test(openai): include codex mini catalog expectation

* test(openai): follow codex catalog fixture split

---------

Co-authored-by: Ke Wang <ke@pika.art>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sessions_spawn rejects non-delivery channels (heartbeat, webhook, cron)

3 participants