Summary
sessions_spawn for runtime: "subagent" is documented as a non-blocking sub-agent spawn path that announces results back to the requester chat, but in real use the request path can still end up carrying streamTo: "parent", which causes the validator to reject the call with:
streamTo is only supported for runtime=acp; got runtime=subagent
In the same environment, runtime: "acp" with streamTo: "parent" works correctly, so this appears to be a subagent request-construction / wrapper-layer issue rather than a general gateway failure.
Environment
- OpenClaw docs consulted:
https://docs.openclaw.ai/concepts/session-tool#sessions_spawn
https://docs.openclaw.ai/tools/subagents
- Runtime observed in-session:
openclaw/gpt-5.4
- Channel: Feishu direct chat
- Gateway was restarted multiple times during validation
agents.list[].subagents.allowAgents was configured and reloaded successfully
agents.defaults.subagents was also configured successfully (maxSpawnDepth, maxChildrenPerAgent, maxConcurrent, runTimeoutSeconds)
Expected behavior
For runtime: "subagent", a clean sessions_spawn request should work without requiring ACP-only parameters.
Per docs, a valid subagent spawn is expected to accept parameters like:
{
"task": "Who are you?",
"runtime": "subagent",
"agentId": "shrimp-pm",
"runTimeoutSeconds": 120,
"cleanup": "keep"
}
Expected result:
sessions_spawn returns { status: "accepted", runId, childSessionKey }
- child session runs as
agent:<agentId>:subagent:<uuid>
- completion is announced back to requester
Actual behavior
The request is rejected at validation time with:
streamTo is only supported for runtime=acp; got runtime=subagent
This is happening even though the subagent docs do not require streamTo, and streamTo is ACP-specific by design.
Evidence / observations
1. Backend validation clearly rejects ACP-only streamTo on subagent runtime
From the built artifact (/app/node_modules/openclaw/dist/model-selection-46xMp11W.js in the tested environment):
const streamTo = params.streamTo === "parent" ? "parent" : void 0;
...
if (streamTo && runtime !== "acp") return jsonResult({
status: "error",
error: `streamTo is only supported for runtime=acp; got runtime=${runtime}`
});
2. spawnSubagentDirect(...) itself is non-streaming / completion-message oriented
The same implementation path uses:
return jsonResult(await spawnSubagentDirect({
...,
expectsCompletionMessage: true,
...
}))
This matches the docs: subagents are non-blocking and announce their result back after completion.
3. ACP path works in the same environment
A control test with ACP succeeded:
{
"task": "Reply with exactly ACP_STREAM_TEST_OK",
"runtime": "acp",
"agentId": "codex",
"streamTo": "parent"
}
Observed result:
status: "accepted"
- child ACP session created
- stream log path returned
- task completed successfully
So this is not a general spawn failure.
4. Subagent functionality itself is not globally broken
Using the /subagents spawn ... path (which routes to spawnSubagentDirect(...)) successfully produced real subagent runs and completion announces for multiple OpenClaw agents.
This strongly suggests the issue is specific to how sessions_spawn requests are being constructed / normalized before execution, not to the subagent runtime itself.
Reproduction steps
- Configure two standard OpenClaw agents (non-ACP) and allow cross-agent subagent spawning via:
{
"agents": {
"list": [
{
"id": "parent-agent",
"subagents": {
"allowAgents": ["child-agent"]
}
},
{
"id": "child-agent"
}
]
}
}
- Restart gateway.
- From the parent agent session, call
sessions_spawn for a standard child agent using runtime: "subagent".
- Observe that the call can fail with:
streamTo is only supported for runtime=acp; got runtime=subagent
- In the same environment, call
sessions_spawn with runtime: "acp" and streamTo: "parent".
- Observe ACP succeeds.
Why this is confusing
The docs for subagents and sessions_spawn clearly describe subagents as:
- isolated
- non-blocking
- completion/announce-driven
- separate from ACP
So when a caller follows the documented subagent semantics, getting an ACP-only streamTo validation error is surprising and makes it look like the caller has no clean way to submit a valid subagent request.
Suspected root cause
A wrapper / request-construction layer is likely injecting or preserving streamTo: "parent" for requests that are ultimately sent as runtime: "subagent".
In other words, the problem appears to be pre-validator parameter pollution, not the subagent runtime itself.
Suggested fix
Defensively normalize sessions_spawn inputs before validation / dispatch:
- if
runtime !== "acp", strip ACP-only fields such as:
Example normalization:
if (runtime !== "acp") {
streamTo = undefined;
resumeSessionId = undefined;
}
Even if the higher-level caller should be fixed, this defensive normalization would make the API more robust and align runtime behavior with the docs.
Impact
This blocks reliable use of sessions_spawn for real OpenClaw multi-agent orchestration under the documented subagent model, especially when trying to use it for cross-agent team-style delegation.
Summary
sessions_spawnforruntime: "subagent"is documented as a non-blocking sub-agent spawn path that announces results back to the requester chat, but in real use the request path can still end up carryingstreamTo: "parent", which causes the validator to reject the call with:In the same environment,
runtime: "acp"withstreamTo: "parent"works correctly, so this appears to be a subagent request-construction / wrapper-layer issue rather than a general gateway failure.Environment
https://docs.openclaw.ai/concepts/session-tool#sessions_spawnhttps://docs.openclaw.ai/tools/subagentsopenclaw/gpt-5.4agents.list[].subagents.allowAgentswas configured and reloaded successfullyagents.defaults.subagentswas also configured successfully (maxSpawnDepth,maxChildrenPerAgent,maxConcurrent,runTimeoutSeconds)Expected behavior
For
runtime: "subagent", a cleansessions_spawnrequest should work without requiring ACP-only parameters.Per docs, a valid subagent spawn is expected to accept parameters like:
{ "task": "Who are you?", "runtime": "subagent", "agentId": "shrimp-pm", "runTimeoutSeconds": 120, "cleanup": "keep" }Expected result:
sessions_spawnreturns{ status: "accepted", runId, childSessionKey }agent:<agentId>:subagent:<uuid>Actual behavior
The request is rejected at validation time with:
This is happening even though the subagent docs do not require
streamTo, andstreamTois ACP-specific by design.Evidence / observations
1. Backend validation clearly rejects ACP-only
streamToon subagent runtimeFrom the built artifact (
/app/node_modules/openclaw/dist/model-selection-46xMp11W.jsin the tested environment):2.
spawnSubagentDirect(...)itself is non-streaming / completion-message orientedThe same implementation path uses:
This matches the docs: subagents are non-blocking and announce their result back after completion.
3. ACP path works in the same environment
A control test with ACP succeeded:
{ "task": "Reply with exactly ACP_STREAM_TEST_OK", "runtime": "acp", "agentId": "codex", "streamTo": "parent" }Observed result:
status: "accepted"So this is not a general spawn failure.
4. Subagent functionality itself is not globally broken
Using the
/subagents spawn ...path (which routes tospawnSubagentDirect(...)) successfully produced real subagent runs and completion announces for multiple OpenClaw agents.This strongly suggests the issue is specific to how
sessions_spawnrequests are being constructed / normalized before execution, not to the subagent runtime itself.Reproduction steps
{ "agents": { "list": [ { "id": "parent-agent", "subagents": { "allowAgents": ["child-agent"] } }, { "id": "child-agent" } ] } }sessions_spawnfor a standard child agent usingruntime: "subagent".sessions_spawnwithruntime: "acp"andstreamTo: "parent".Why this is confusing
The docs for subagents and
sessions_spawnclearly describe subagents as:So when a caller follows the documented subagent semantics, getting an ACP-only
streamTovalidation error is surprising and makes it look like the caller has no clean way to submit a valid subagent request.Suspected root cause
A wrapper / request-construction layer is likely injecting or preserving
streamTo: "parent"for requests that are ultimately sent asruntime: "subagent".In other words, the problem appears to be pre-validator parameter pollution, not the subagent runtime itself.
Suggested fix
Defensively normalize
sessions_spawninputs before validation / dispatch:runtime !== "acp", strip ACP-only fields such as:streamToresumeSessionIdExample normalization:
Even if the higher-level caller should be fixed, this defensive normalization would make the API more robust and align runtime behavior with the docs.
Impact
This blocks reliable use of
sessions_spawnfor real OpenClaw multi-agent orchestration under the documented subagent model, especially when trying to use it for cross-agent team-style delegation.