Skip to content

fix: expose resolvedTo as currentChannelId so sub-agents inherit thread routing#22205

Closed
Galygious wants to merge 1 commit into
openclaw:mainfrom
Galygious:fix/subagent-thread-inheritance
Closed

fix: expose resolvedTo as currentChannelId so sub-agents inherit thread routing#22205
Galygious wants to merge 1 commit into
openclaw:mainfrom
Galygious:fix/subagent-thread-inheritance

Conversation

@Galygious

@Galygious Galygious commented Feb 20, 2026

Copy link
Copy Markdown

Summary

When a sub-agent is spawned via sessions_spawn, the gateway's agent handler already receives and resolves to and threadId from the requester session context. However, resolvedTo was never mapped to runContext.currentChannelId, leaving the message tool's zero-param target inference with nothing to fall back on.

Symptom: Sub-agents calling message with action=send and no explicit to, channel, or threadId would fail with Action send requires a target — even though the parent session had a fully-resolved delivery target.

Root Cause

buildThreadingToolContext() (in agent-runner-utils.ts) sets currentChannelId = sessionCtx.To?.trim() for the main session. For sub-agents launched via sessions_spawn, sessionCtx.To is empty because the sub-agent session has no inbound message context — it only has the runContext passed from the gateway handler. resolvedTo was present in that handler but was never forwarded into runContext.currentChannelId.

Fix

One line added to src/gateway/server-methods/agent.ts:

// Before
runContext: {
  messageChannel: resolvedChannel,
  // ...
  currentThreadTs: resolvedThreadId != null ? String(resolvedThreadId) : undefined,
},

// After
runContext: {
  messageChannel: resolvedChannel,
  // ...
  currentThreadTs: resolvedThreadId != null ? String(resolvedThreadId) : undefined,
  currentChannelId: resolvedTo || undefined,
},

This flows through: agentCommandrunEmbeddedPiAgentcreateOpenClawCodingToolscreateMessageTool → tool context inference in message-action-runner.ts.

Verification

Tested end-to-end on Discord thread sessions:

  • Sub-agent spawned with prompt Count to 10. Send each number as a separate message. — no thread info passed
  • All 10 messages delivered to the correct Discord thread (channel:1474502983390593189)
  • Zero explicit to, channel, or threadId params used by the sub-agent

Explicit routing params still take full precedence when provided. This change only affects the fallback inference path.

Drawbacks / Considerations

  • Sub-agents now silently inherit the parent's delivery target. Previously they'd error if to was omitted; now they succeed and send to the parent thread. This is almost always desirable but worth noting as a behavior change for sub-agents intended to run silently.
  • Cron/hook-spawned sub-agents will inherit whatever resolvedTo the triggering context resolves to, which may be an unrelated channel. Same mitigation as always: pass an explicit to to override.

AI-Submitted PR

⚠️ This PR was identified, implemented, and submitted by Cognis, an AI agent running on OpenClaw (user: Galygious). It has been manually end-to-end tested as described above but has not been run through the automated test suite. Please review accordingly.

A regression test covering sub-agent message tool target inference (verifying currentChannelId is populated from resolvedTo in the agent handler) would be a valuable addition.

When a sub-agent is spawned via sessions_spawn, the gateway agent
handler already forwards to and threadId from the requester session.
However, resolvedTo was never mapped to runContext.currentChannelId,
so the message tool zero-param target inference had nothing to fall
back on -- resulting in 'Action send requires a target' errors.

Sets currentChannelId: resolvedTo in the runContext, flowing through
runEmbeddedPiAgent -> createOpenClawCodingTools -> createMessageTool.
Sub-agents calling message with no explicit to/channel/threadId now
inherit the parent session's originating thread/channel automatically.

Verified end-to-end: sub-agents spawned with only a task prompt send
Discord messages to the correct thread without explicit routing params.

AI-submitted: identified and implemented by Cognis (OpenClaw agent).
Manual end-to-end tested. No automated test suite run. A regression
test for sub-agent message tool target inference would be a good add.
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: XS labels Feb 20, 2026
@Galygious

Copy link
Copy Markdown
Author

Note on CI failures: The failing checks (src/web/media.test.ts — image compression/MEDIA prefix tests) are pre-existing failures on main that predate this PR by several commits. They are unrelated to this change, which only touches src/gateway/server-methods/agent.ts.

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Feb 28, 2026
@Galygious

Copy link
Copy Markdown
Author

im not sure why this was marked stale. still a valid pull request to my knowledge

@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Mar 20, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Mar 30, 2026
@openclaw-barnacle

Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, post in #pr-thunderdome-dangerzone on Discord to talk to a maintainer.
That channel is the escape hatch for high-quality PRs that get auto-closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime size: XS stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant