openclaw - ✅(Solved) Fix [Bug]: sessions_spawn(runtime="subagent") can receive ACP-only streamTo from the current tool-call bridge [1 pull requests, 4 comments, 5 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#56193Fetched 2026-04-08 01:43:49
View on GitHub
Comments
4
Participants
5
Timeline
6
Reactions
0
Timeline (top)
commented ×4cross-referenced ×1subscribed ×1

Error Message

That leads to an error like:

Root Cause

A minimal sessions_spawn attempt for runtime="subagent" failed before entering normal spawn flow because streamTo was present in the executed args.

Fix Action

Fixed

PR fix notes

PR #56203: fix(sessions_send): prefer sessionKey over label when both are present (AI-assisted)

Description (problem / solution / changelog)

Summary

  • Problem: sessions_send exposed both sessionKey and label in its tool schema, but hard-failed when both were present.
  • Why it matters: real tool-call pipelines can redundantly provide both fields, causing cross-session sends to fail even when sessionKey is a precise target.
  • What changed: sessions_send now prefers sessionKey when both fields are present and only falls back to label resolution when sessionKey is absent.
  • What did NOT change (scope boundary): label-only targeting still works, and no cross-agent policy / visibility rules were changed.

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
  • API / contracts
  • Auth / tokens
  • Memory / storage
  • Integrations
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Related #56193
  • This PR fixes a bug or regression

Root Cause / Regression History (if applicable)

  • Root cause: sessions_send accepted both sessionKey and label in its schema but treated their coexistence as an error, even though upstream tool-call adapters / hook-based param merging can legitimately surface both.
  • Missing detection / guardrail: there was no test asserting deterministic behavior when both selectors are present, and no executor-side preference for the less ambiguous selector.
  • Prior context (git blame, prior PR, issue, or refactor if known): not fully traced to a single introducing change; reviewed current sessions_send implementation plus surrounding tool adapter / before_tool_call paths.
  • Why this regressed now: real automated tool invocation paths are more tolerant/expansive than the manual “exactly one field” assumption encoded in the executor.
  • If unknown, what was ruled out: I ruled out an obvious dedicated upstream adapter that explicitly copies sessionKey into label; the failure appears to come from interface fragility rather than one single injector.

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/agents/tools/sessions.test.ts
  • Scenario the test should lock in:
    • when sessionKey and label are both present, sessions_send should prefer sessionKey, skip sessions.resolve, and complete normally
  • Why this is the smallest reliable guardrail:
    • the behavior lives directly in the executor branching logic, so unit coverage at the tool layer is the narrowest stable check
  • Existing test that already covers this (if any):
    • existing tests covered sessionKey-only and label-only flows, but not coexistence
  • If no new test is added, why not:
    • N/A

User-visible / Behavior Changes

  • sessions_send no longer errors with Provide either sessionKey or label (not both) when both fields are present.
  • When both are present, sessionKey wins.
  • label remains supported as a fallback targeting mechanism when sessionKey is absent.

Diagram (if applicable)

Before:
tool call -> { sessionKey, label } -> sessions_send -> hard error

After:
tool call -> { sessionKey, label } -> sessions_send -> use sessionKey -> send succeeds

Security Impact (required)

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

This changes tool execution behavior for sessions_send conflict handling. Risk: callers that relied on the previous strict error could now proceed. Mitigation: the new behavior prefers the more explicit selector (sessionKey) and preserves all existing visibility, agent-to-agent policy, and label-only resolution checks.

Repro + Verification

Environment

  • OS: Linux (WSL2)
  • Runtime/container: local OpenClaw install + source checkout
  • Model/provider: ai/gpt-5.4
  • Integration/channel (if any): inter-session send from explore to main
  • Relevant config (redacted): default local setup; no special config required for repro beyond available session tools

Steps

  1. Call sessions_send with both sessionKey and label
  2. Target a valid session such as main
  3. Observe executor behavior before and after patch

Expected

  • The executor should prefer sessionKey
  • It should not fail just because label is also present
  • It should only resolve by label when sessionKey is absent

Actual

  • Before patch: immediate error Provide either sessionKey or label (not both)
  • After patch: request proceeds normally and uses sessionKey

Evidence

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

Evidence gathered:

  • src/agents/tools/sessions.test.ts → 19 passed
  • src/agents/openclaw-tools.sessions.test.ts → 24 passed
  • src/gateway/server.sessions-send.test.ts → 2 passed

Runtime validation:

  • Before patch: sessions_send from explore -> main failed with Provide either sessionKey or label (not both)
  • After patch:
    • timeoutSeconds=10 → reached send/wait flow, returned timeout
    • timeoutSeconds=30 → returned status: "ok", reply: "收到2"

This confirms the original parameter-conflict bug is fixed.

Human Verification (required)

  • Verified scenarios:
    • confirmed source change in src/agents/tools/sessions-send-tool.ts
    • added focused regression test
    • ran targeted tool-layer, integration-layer, and gateway-layer tests successfully
    • verified real runtime behavior against the installed OpenClaw instance after rebuilding and deploying patched artifacts
  • Edge cases checked:
    • sessionKey only still works
    • label only still works
    • sessionKey + label now uses sessionKey
    • no regression observed in higher-level session tool test suites
  • What you did not verify:
    • full pnpm check
    • full repository pnpm test
    • remote deployment / packaged release flow

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.

Compatibility / Migration

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

Risks and Mitigations

  • Risk:

    • A caller that intentionally depended on the old hard error for mixed selectors will now proceed instead.
    • Mitigation:
      • sessionKey is the more explicit selector, so preferring it is deterministic and safer than failing on redundant input.
  • Risk:

    • There may still be another upstream path that injects redundant params unexpectedly.
    • Mitigation:
      • This patch makes the executor robust to that class of redundancy and adds regression coverage.

Changed files

  • src/agents/tools/sessions-send-tool.ts (modified, +2/-7)
  • src/agents/tools/sessions.test.ts (modified, +45/-0)

Code Example

streamTo is only supported for runtime=acp; got runtime=subagent

---

streamTo is only supported for runtime=acp; got runtime=subagent
RAW_BUFFERClick to expand / collapse

Bug Description

sessions_spawn correctly defines streamTo as an ACP-only field, and the executor explicitly rejects it when runtime !== "acp".

However, in the current tool-call path I observed sessions_spawn(runtime="subagent") receiving streamTo anyway, even though the intended call was a minimal subagent spawn.

That leads to an error like:

streamTo is only supported for runtime=acp; got runtime=subagent

This looks like a parameter pollution / tool-call bridge issue rather than a sessions_spawn business-logic issue.

Expected Behavior

When a caller intends a plain subagent spawn, the actual executed params should not contain ACP-only fields such as streamTo.

In other words:

  • runtime="subagent" calls should arrive without ACP-only routing fields
  • streamTo should only appear for genuine ACP spawn flows

Actual Behavior

A minimal sessions_spawn attempt for runtime="subagent" failed before entering normal spawn flow because streamTo was present in the executed args.

The executor then correctly rejected it with:

streamTo is only supported for runtime=acp; got runtime=subagent

What I checked

streamTo is intentionally ACP-only

Relevant code:

  • src/agents/acp-spawn.ts
  • src/agents/tools/sessions-spawn-tool.ts

streamTo was introduced for ACP parent-streaming behavior and has valid ACP semantics.

sessions_spawn core logic appears correct

sessions-spawn-tool.ts explicitly does:

  • parse streamTo
  • reject it when runtime !== "acp"

That part looks intentional and correct.

I did not find evidence that core sessions_spawn logic itself injects streamTo

Searching the core source only found streamTo in:

  • ACP spawn logic
  • sessions_spawn schema/tool implementation
  • related tests

I did not find a separate OpenClaw core business layer that obviously injects streamTo into subagent calls.

Likely problem area

This makes the problem look more like:

  • tool-call bridge / adapter layer
  • parameter serialization / propagation layer
  • or some higher-level invocation path that carries optional schema fields into actual tool execution

Environment

  • OpenClaw version: local source checkout based on 2026.3.24
  • Runtime: local Linux / WSL2
  • Channel/surface: tool invocation path from active agent session
  • Observed during manual runtime validation

Suggested investigation direction

Please check the current tool-call bridge / adapter path for sessions_spawn and confirm whether optional schema fields are being propagated into actual executed params even when not intentionally requested.

extent analysis

Fix Plan

To resolve the issue, we need to ensure that the streamTo field is not propagated to the sessions_spawn tool when the runtime is not ACP. Here are the steps to fix the issue:

  • Modify the sessions-spawn-tool.ts to filter out ACP-only fields when the runtime is not ACP.
  • Update the tool-call bridge / adapter layer to not include optional schema fields in the executed params unless they are explicitly requested.

Example code:

// sessions-spawn-tool.ts
if (runtime !== "acp") {
  delete params.streamTo; // remove streamTo field when runtime is not ACP
}

// tool-call bridge / adapter layer
const executedParams = {};
for (const key in params) {
  if (params.hasOwnProperty(key) && (runtime === "acp" || !isAcpOnlyField(key))) {
    executedParams[key] = params[key];
  }
}

function isAcpOnlyField(key) {
  // implement logic to check if a field is ACP-only
  // for example:
  return key === "streamTo";
}

Verification

To verify that the fix worked, you can test the sessions_spawn tool with different runtime values and check that the streamTo field is only included in the executed params when the runtime is ACP.

Extra Tips

  • Make sure to update the documentation and tests to reflect the changes made to the sessions-spawn-tool.ts and the tool-call bridge / adapter layer.
  • Consider adding additional logging or debugging statements to help identify and diagnose similar issues in the future.

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