sessions_spawn fails when commander delegates via natural language
Env: OpenClaw 2026.4.11, WSL2 Ubuntu, Telegram, claude-sonnet-4-6 as main-commander
Works
/subagents spawn chammo "question" β works perfectly
Direct chat with commander β works fine
Fails
Natural language delegation like "Tell chammo to compare X and Y" β commander tries sessions_spawn tool call internally β fails every time.
Error from logs
streamTo is only supported for runtime=acp; got runtime=subagent
ENOENT: no such file or directory '.openclaw/agents/chammo/logs/error.log'
Offset 366 is beyond end of file (275 lines total) AGENTS.md
The model keeps adding streamTo: "parent" to sessions_spawn calls. Since my agents use subagent runtime, the framework rejects it.
Config (relevant)
{
"id": "main-commander",
"subagents": { "allowAgents": ["ops","chammo","inspector"], "requireAgentId": true }
}
Subagents: chammo (gemini-2.5-flash), ops (gpt-4.1-mini), inspector (claude-opus-4-6)
What I tried
Prompt rules in SOUL.md/AGENTS.md/main-commander.md saying "never use streamTo" β model ignores it
Commented out streamTo from tool schema (line 7382 openclaw-tools JS) β still fails
Commented out streamTo validation error (line 7421-7424) β still fails
Created missing directories for agent logs β not confirmed
Questions
How to prevent the model from adding streamTo: "parent" to sessions_spawn in subagent runtime?
Is there a config to force subagent-only spawn without ACP fields?
Could missing log dirs / AGENTS.md offset error be causing spawn failure independently?
What's the recommended pattern for natural language commander β subagent delegation?
Manual /subagents spawn works β just need the commander to do it automatically.
#sessions_spawn fails when commander delegates via natural language
88 messages Β· Page 1 of 1 (latest)
Let me check the local docs tree so I can answer this without guessing.
Iβm checking the two secondary errors too, because those smell like separate bugs from the streamTo issue.
Root cause is almost certainly the unified sessions_spawn tool shape, not your subagent setup.
/subagents spawn ...works, so subagent runtime is fine.- Natural language goes through
sessions_spawn, and in current code that tool accepts both:- subagent params
- ACP-only params like
streamTo
- Then it hard-rejects
streamTowhenruntime !== "acp".
So:
-
How to stop
streamTo: "parent"?
Not reliably with prompt rules alone. The model seesstreamToin the tool schema, so some models over-specify it. -
Is there a config to force subagent-only spawn?
I donβt see one. The documented subagent config is things likeallowAgentsandrequireAgentId, not βstrip ACP fieldsβ or βforce runtime=subagentβ.
Docs: https://docs.openclaw.ai/tools/subagents
Config ref: https://docs.openclaw.ai/gateway/configuration-reference
-
Are the
error.log/ AGENTS offset errors the cause?
Probably independent. ThestreamTovalidation happens before the actual subagent spawn path, so that alone is enough to fail the call. Those other errors are worth fixing, but they are very likely secondary noise, not the blocker. -
Recommended pattern
For commander β worker delegation, use:sessions_spawnwith onlyagentId+taskfor one-shot work- no
thread, nomode, nostreamTounless you explicitly want ACP/thread behavior
For persistent specialists, spawn once withthread: true, mode: "session"and then reuse viasessions_send/ bound thread.
Practical workaround today
If you do not use ACP at all, set:
{
acp: { enabled: false }
}
That should reduce prompt/tooling confusion, though it is not as strong as a real schema split.
If you do need both ACP and subagents, the robust fix is upstream:
- either split
sessions_spawninto separate runtime-specific tools/schemas - or server-side sanitize
streamToaway forruntime: "subagent"instead of rejecting
Thatβs a real bug/UX gap, honestly. Iβd file it here:
https://github.com/openclaw/openclaw/issues
One extra thing: if your local code edits βdid nothingβ, double-check you patched the active install/build artifact and restarted the gateway. Editing one JS file in the wrong tree is easy to do here.
If you want, paste openclaw status --all plus the exact agents.list entries for main-commander and chammo, and Iβll help sanity-check the secondary errors too.
Thanks for confirming this is a bug/UX gap. I'll file a GitHub issue.
For the secondary errors, here's what I'm seeing:
-
I did patch the active install at
/usr/lib/node_modules/openclaw/dist/openclaw-tools-C-4xhzGY.js(commented out streamTo schema line 7382 and validation lines 7421-7424), then restarted withpkill -f openclaw && openclaw &. Still failed β maybe I missed another validation point? -
Here's my config and status:
That exact error string is distinctive. Iβm checking whether it exists anywhere else, because if itβs only in one place then your patched file probably isnβt the code path actually running.
I donβt think you missed a second validation point.
I checked the current code, and that exact error string only exists in one non-test place: sessions-spawn-tool.ts. So if you still see:
streamTo is only supported for runtime=acp
after patching /usr/lib/node_modules/openclaw/dist/openclaw-tools-C-4xhzGY.js, the most likely explanation is:
- that is not the code path actually serving Telegram, or
- the gateway daemon restarted from a different install/path, or
openclaw &started a different process than the one handling chat traffic.
Also, Iβd avoid pkill ... && openclaw & here. Use the gateway service commands instead:
openclaw gateway restart
openclaw gateway status
openclaw status --all
which openclaw
readlink -f "$(which openclaw)"
node -p "require.resolve('openclaw/package.json')"
pgrep -af openclaw
What Iβm looking for:
- does
which openclawpoint at the same install you patched? - is the running gateway actually using that install?
- are there two OpenClaw installs/processes?
On the secondary errors:
Offset 366 is beyond end of file ... AGENTS.mdlooks like a read past EOF, not the spawn blocker.ENOENT ... .openclaw/agents/chammo/logs/error.loglooks like a separate per-agent logging/bootstrap issue, also not the reason that exactstreamTovalidation keeps firing.
So yes, those may be real bugs too, but theyβre probably independent.
I donβt see your config/status paste in the message, looks like Discord ate it. If you paste these, I can narrow it down fast:
openclaw gateway statusopenclaw status --all- output of:
which openclawreadlink -f "$(which openclaw)"node -p "require.resolve('openclaw/package.json')"
- the full
agents.listentries formain-commanderandchammo
Docs, for reference:
https://docs.openclaw.ai/help/faq
ddariggun@DESKTOP-2V3KBST:/mnt/c/WINDOWS/system32$ openclaw gateway status
π¦ OpenClaw 2026.4.11 (769908e) β Powered by open source, sustained by spite and good documentation.
β
β
Service: systemd (enabled)
File logs: /tmp/openclaw/openclaw-2026-04-15.log
Command: /usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js gateway --port 18789
Service file: ~/.config/systemd/user/openclaw-gateway.service
Service env: OPENCLAW_GATEWAY_PORT=18789
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
Gateway: bind=loopback (127.0.0.1), port=18789 (service args)
Probe target: ws://127.0.0.1:18789
Dashboard: http://127.0.0.1:18789/
Probe note: Loopback-only gateway; only local clients can connect.
Runtime: running (pid 3055, state active, sub running, last exit 0, reason 0)
RPC probe: ok
Listening: 127.0.0.1:18789
Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting
Nice, this helps a lot.
This rules out the big PATH mismatch I was worried about. Your daemon really is running:
/usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js gateway --port 18789
So your patched /usr/lib/node_modules/openclaw/dist/... tree is at least the right install root.
What it does not prove yet is that openclaw-tools-C-4xhzGY.js is the exact compiled chunk serving that code path.
What Iβd do next
- Restart the actual service cleanly
notopenclaw gateway restartpkill ... && openclaw &
- Search the whole dist tree for that exact error string
rg -n "streamTo is only supported for runtime=acp" /usr/lib/node_modules/openclaw/dist
Interpretation:
-
1 match and it is the file you edited, but the string is still present
β the edit did not actually remove that code path -
multiple matches
β there is another compiled copy/chunk, and you patched the wrong one -
0 matches, but runtime still throws that exact message
β the service did not restart onto the patched code, or you are somehow not hitting the service you think you are
Secondary errors
They still look separate to me:
ENOENT ... chammo/logs/error.log= per-agent logging/bootstrap issueOffset 366 ... AGENTS.md= read past EOF
Neither explains why the exact streamTo validation message keeps coming back.
One more paste that would help
Please paste:
openclaw status --all
rg -n "streamTo is only supported for runtime=acp" /usr/lib/node_modules/openclaw/dist
If that rg output shows more than one file, Iβm pretty confident weβve found why your patch βdid nothing.β
Troubleshooting docs:
https://docs.openclaw.ai/help/faq
https://docs.openclaw.ai/gateway/troubleshooting
ddariggun@DESKTOP-2V3KBST:/mnt/c/WINDOWS/system32$ openclaw status --all
π¦ OpenClaw 2026.4.11 (769908e) β I run on caffeine, JSON5, and the audacity of "it worked on my machine."
β
OpenClaw status --all
Overview
βββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Item β Value β
βββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Version β 2026.4.11 β
β OS β linux 6.6.87.2-microsoft-standard-WSL2 (x64) β
β Node β 22.22.2 β
β Config β ~/.openclaw/openclaw.json β
β Dashboard β http://127.0.0.1:18789/ β
β Tailscale β off β
β Channel β stable (default)
β Update β pnpm Β· npm update 2026.4.14 β
β Gateway β local Β· ws://127.0.0.1:18789 (local loopback) Β· reachable 57ms Β· auth token Β· DESKTOP-2V3KBST β
β β (192.168.235.215) app 2026.4.11 linux 6.6.87.2-microsoft-standard-WSL2 β
β Security β Run: openclaw security audit --deep β
β Gateway self β unknown β
β Gateway service β systemd installed Β· enabled Β· running (pid 3055, state active) β
β Node service β systemd not installed β
β Agents β 4 total Β· 4 bootstrapping Β· 1 active Β· 17 sessions β
β Secrets β none β
βββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Channels
ββββββββββββ¬ββββββββββ¬βββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Channel β Enabled β State β Detail β
ββββββββββββΌββββββββββΌβββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Telegram β ON β OK β token config (sha256:bbd4aec6 Β· len 46) Β· accounts 1/1 β
ββββββββββββ΄ββββββββββ΄βββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Telegram accounts
ββββββββββββ¬βββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Account β Status β Notes β
ββββββββββββΌβββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β default β OK β token:config β
ββββββββββββ΄βββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Agents
ββββββββββββββββββ¬βββββββββββββββββ¬βββββββββββ¬βββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Agent β Bootstrap file β Sessions β Active β Store β
ββββββββββββββββββΌβββββββββββββββββΌβββββββββββΌβββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β main-commander β PRESENT β 6 β 8m ago β ~/.openclaw/agents/main-commander/sessions/sessions.json β
β chammo β PRESENT β 11 β 25m ago β ~/.openclaw/agents/chammo/sessions/sessions.json β
β inspector β PRESENT β 0 β unknown β ~/.openclaw/agents/inspector/sessions/sessions.json β
β ops β PRESENT β 0 β unknown β ~/.openclaw/agents/ops/sessions/sessions.json β
ββββββββββββββββββ΄βββββββββββββββββ΄βββββββββββ΄βββββββββββ΄β
Diagnosis (read-only)
Gateway connection details:
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/ddariggun/.openclaw/openclaw.json
Bind: loopback
β Config: /home/ddariggun/.openclaw/openclaw.json
β Secret diagnostics (0)
β Restart sentinel: none
! Port 18789
Port 18789 is already in use.
- pid 3055 ddariggun: openclaw-gateway (127.0.0.1:18789)
- Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
! Tailscale: off Β· unknown
β Skills: 7 eligible Β· 0 missing Β· /home/ddariggun/.openclaw/workspace
β Plugin compatibility (none)
β Channel issues (none)
Pasteable debug report. Auth tokens redacted.
Troubleshooting: https://docs.openclaw.ai/troubleshooting
Thanks, that confirms the environment, but the part we need is still the dist grep. The full status --all table wonβt tell us why your patch didnβt bite.
Please run just this and paste the output:
openclaw gateway restart
grep -R -n "streamTo is only supported for runtime=acp" /usr/lib/node_modules/openclaw/dist
That one command should settle it:
- 0 matches β your running gateway is still somehow using unpatched code
- 1 match β the edit didnβt actually remove the active check
- 2+ matches β there are multiple compiled copies/chunks, and you patched the wrong one
If you want, also add this right after:
grep -R -n "streamTo" /usr/lib/node_modules/openclaw/dist | head -40
At this point Iβm pretty confident the issue is in the compiled dist layout, not your agent config.
β
ddariggun@DESKTOP-2V3KBST:/mnt/c/WINDOWS/system32$ cat ~/.openclaw/openclaw.json
{
"agents": {
"defaults": {
"workspace": "/home/ddariggun/.openclaw/workspace",
"model": {
"primary": "anthropic/claude-sonnet-4-6",
"fallbacks": [
"openrouter/google/gemini-2.5-flash",
"openrouter/openai/gpt-4.1-mini"
]
},
"subagents": {
"allowAgents": [
"*"
],
"requireAgentId": true,
"archiveAfterMinutes": 60
}
},
"list": [
{
"id": "main-commander",
"default": true,
"model": {
"primary": "anthropic/claude-sonnet-4-6",
"fallbacks": [
"openrouter/google/gemini-2.5-flash",
"openrouter/openai/gpt-4.1-mini"
]
},
"subagents": {
"allowAgents": [
"ops",
"chammo",
"inspector"
],
"requireAgentId": true
}
},
{
"id": "ops",
"model": {
"primary": "openrouter/openai/gpt-4.1-mini",
"fallbacks": [
"anthropic/claude-sonnet-4-6",
"openrouter/google/gemini-2.5-flash"
]
}
},
{
"id": "chammo",
"model": {
"primary": "openrouter/google/gemini-2.5-flash",
"fallbacks": [
"openrouter/google/gemini-2.5-flash-lite",
"anthropic/claude-sonnet-4-6"
]
}
},
{
"id": "inspector",
"model": {
"primary": "anthropic/claude-opus-4-6",
"fallbacks": [
"anthropic/claude-sonnet-4-6"
]
}
}
]
},
"gateway": {
"mode": "local",
"auth": {
"mode": "token",
"token": "f8fced8a84685eff8a44f77fcc1f369787dfcfc34511ac8d"
},
"port": 18789,
"bind": "loopback",
"tailscale": {
"mode": "off",
"resetOnExit": false
},
"controlUi": {
"allowInsecureAuth": true
},
"nodes": {
"denyCommands": [
"camera.snap",
"camera.clip",
"screen.record",
"contacts.add",
"calendar.add",
"reminders.add",
"sms.send",
"sms.search"
]
}
},
"session": {
"dmScope": "per-channel-peer"
},
"tools": {
"profile": "coding"
},
"auth": {
"profiles": {
"anthropic:default": {
"provider": "anthropic",
"mode": "api_key"
},
"openrouter:default": {
"provider": "openrouter",
"mode": "api_key"
}
}
},
"channels": {
"telegram": {
"enabled": true,
"groups": {
"*": {
"requireMention": true
}
},
"botToken": "8228988924:AAF1gRSEmKmyQfwq7r4ql8qdruwwUjcjXgk"
}
},
"plugins": {
"entries": {
"anthropic": {
"enabled": true
},
"openrouter": {
"enabled": true
},
"codex": {
"enabled": true
},
"openai": {
"enabled": true
}
}
},
"meta": {
"lastTouchedVersion": "2026.4.11",
"lastTouchedAt": "2026-04-13T12:23:27.144Z"
}
}
ddariggun@DESKTOP-2V3KBST:/mnt/c/WINDOWS/system32$
ddariggun@DESKTOP-2V3KBST:/mnt/c/WINDOWS/system32$ node -p "require.resolve('openclaw/package.json')"
node:internal/modules/cjs/loader:1386
throw err;
^
Error: Cannot find module 'openclaw/package.json'
Require stack:
- /mnt/c/WINDOWS/system32/[eval]
at Function._resolveFilename (node:internal/modules/cjs/loader:1383:15)
at Function.resolve (node:internal/modules/helpers:157:19)
at [eval]:1:9
at runScriptInThisContext (node:internal/vm:209:10)
at node:internal/process/execution:446:12
at [eval]-wrapper:6:24
at runScriptInContext (node:internal/process/execution:444:60)
at evalFunction (node:internal/process/execution:279:30)
at evalTypeScript (node:internal/process/execution:291:3)
at node:internal/main/eval_string:74:3 {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/mnt/c/WINDOWS/system32/[eval]' ]
}
Node.js v22.22.2
That new status output actually exposed something important: β4 agents bootstrappingβ is not normal. Iβm checking the docs/source around stuck bootstrapping before I tell you to chase the wrong thing.
Ah, that is a real clue.
Agents: 4 total Β· 4 bootstrapping is not just a vague status label. In current code, that count is literally:
βdoes
<workspace>/BOOTSTRAP.mdexist?β
So right now OpenClaw thinks all 4 agent workspaces still have BOOTSTRAP.md present.
Docs say BOOTSTRAP.md is first-run only and should be removed when setup completes:
https://docs.openclaw.ai/start/bootstrapping
https://docs.openclaw.ai/start/openclaw
Why this matters
That probably explains at least part of the weirdness:
- agents stuck acting like they are still in first-run/bootstrap mode
- odd prompt assembly / workspace behavior
- possibly the AGENTS/read noise
I would fix this before chasing the dist patch further.
What Iβd do next
First, list the bootstrap files:
find ~/.openclaw -name BOOTSTRAP.md -print
If those agents are already fully set up, move them aside (safer than deleting):
mv /path/to/BOOTSTRAP.md /path/to/BOOTSTRAP.md.bak
Then restart cleanly:
openclaw gateway restart
openclaw status --all
What you want to see after that:
- bootstrapping count drops from
4to0(or only truly-new agents remain)
My take
4 bootstrappingis definitely a bug/misconfiguration worth fixing- it may explain the secondary weirdness
- the
streamToissue may still be a separatesessions_spawnbug, but Iβd clear the stuck-bootstrap state first because it muddies everything
If you want, paste the output of:
find ~/.openclaw -name BOOTSTRAP.md -print
and Iβll help you sanity-check which ones are safe to move aside.
Telegram looks fine, so that part is probably a distraction.
Also, Discord is chopping up status --all, so letβs stop using that for a minute and do the one check that matters now:
find ~/.openclaw -name BOOTSTRAP.md -print
Please paste just the paths it prints.
Why Iβm focusing on that:
- your status already showed
4 bootstrapping - in current OpenClaw, that basically means
BOOTSTRAP.mdstill exists in those workspaces - that is not normal after setup completes
If it prints the 4 agent workspaces, the next fix is:
- move those
BOOTSTRAP.mdfiles aside toBOOTSTRAP.md.bak openclaw gateway restart- retest delegation
So yeah, no more status --all chunks for now, just the find output π
ddariggun@DESKTOP-2V3KBST:/mnt/c/WINDOWS/system32$ cat ~/.openclaw/openclaw.json
{
"agents": {
"defaults": {
"workspace": "/home/ddariggun/.openclaw/workspace",
"model": {
"primary": "anthropic/claude-sonnet-4-6",
"fallbacks": [
"openrouter/google/gemini-2.5-flash",
"openrouter/openai/gpt-4.1-mini"
]
},
"subagents": {
"allowAgents": [
"*"
],
"requireAgentId": true,
"archiveAfterMinutes": 60
}
},
"list": [
{
"id": "main-commander",
"default": true,
"model": {
"primary": "anthropic/claude-sonnet-4-6",
"fallbacks": [
"openrouter/google/gemini-2.5-flash",
"openrouter/openai/gpt-4.1-mini"
]
},
"subagents": {
"allowAgents": [
"ops",
"chammo",
"inspector"
],
"requireAgentId": true
}
},
{
"id": "ops",
"model": {
"primary": "openrouter/openai/gpt-4.1-mini",
"fallbacks": [
"anthropic/claude-sonnet-4-6",
"openrouter/google/gemini-2.5-flash"
]
}
},
{
{
"id": "chammo",
"model": {
"primary": "openrouter/google/gemini-2.5-flash",
"fallbacks": [
"openrouter/google/gemini-2.5-flash-lite",
"anthropic/claude-sonnet-4-6"
]
}
},
{
"id": "inspector",
"model": {
"primary": "anthropic/claude-opus-4-6",
"fallbacks": [
"anthropic/claude-sonnet-4-6"
]
}
}
]
},
"gateway": {
"mode": "local",
"auth": {
"mode": "token",
"token": "f8fced8a84685eff8a44f77fcc1f369787dfcfc34511ac8d"
},
"port": 18789,
"bind": "loopback",
"tailscale": {
"mode": "off",
"resetOnExit": false
},
"controlUi": {
"allowInsecureAuth": true
},
"nodes": {
"denyCommands": [
"camera.snap",
"camera.clip",
"screen.record",
"contacts.add",
"calendar.add",
"reminders.add",
"sms.send",
"sms.search"
]
}
},
"session": {
"dmScope": "per-channel-peer"
},
"tools": {
"profile": "coding"
},
"auth": {
"profiles": {
"anthropic:default": {
"provider": "anthropic",
"mode": "api_key"
},
"openrouter:default": {
"provider": "openrouter",
"mode": "api_key"
}
}
},
"channels": {
"telegram": {
"enabled": true,
"groups": {
"*": {
"requireMention": true
}
},
"botToken": "8228988924:AAF1gRSEmKmyQfwq7r4ql8qdruwwUjcjXgk"
}
},
"plugins": {
"entries": {
"anthropic": {
"enabled": true
},
"openrouter": {
"enabled": true
},
"codex": {
"enabled": true
},
"openai": {
"enabled": true
}
}
},
"meta": {
"lastTouchedVersion": "2026.4.11",
"lastTouchedAt": "2026-04-13T12:23:27.144Z"
}
}
Iβm still only seeing more status --all sections, not the command output I need π
Please run only this, and paste only its output in a code block:
find ~/.openclaw -name BOOTSTRAP.md -print
Like this:
/home/you/.openclaw/workspace/BOOTSTRAP.md
/home/you/.openclaw/workspace-chammo/BOOTSTRAP.md
...
or:
# no output
That one result will tell us whether the 4 bootstrapping signal is real.
I patched /usr/lib/node_modules/openclaw/dist/openclaw-tools-C-4xhzGY.js lines 7382 and 7421-7424. Let me know if this is the wrong file path.
Also trying openclaw gateway restart instead of pkill && openclaw &.
Yep, thatβs the smoking gun.
Bootstrap file: PRESENT for all 4 agents means OpenClaw still sees every workspace as first-run / bootstrap-pending. That is not normal once those agents are in use.
Docs-wise, BOOTSTRAP.md is supposed to be removed after setup finishes:
https://docs.openclaw.ai/start/bootstrapping
What Iβd do now
-
Find the actual files:
find ~/.openclaw -name BOOTSTRAP.md -print -
If those agents are already set up, move each one aside:
mv /path/to/BOOTSTRAP.md /path/to/BOOTSTRAP.md.bak
-
Restart cleanly:
openclaw gateway restart -
Re-check the Agents section. You want
Bootstrap fileto stop showingPRESENT.
My read
- This definitely explains the
4 bootstrappingstate. - It may also explain some of the other weirdness around prompt/workspace behavior.
- The
streamToproblem may still be a separatesessions_spawnbug, but I would absolutely clear this bootstrap state first before debugging further.
So, good news: we found a real broken thing, not just noise.
After you move those aside and restart, test the natural-language delegation again. If it still throws the same streamTo error, then we go back to the compiled dist / schema bug with much cleaner ground under us.
That diagnosis doesnβt add anything new. It just says the gateway is already running on 18789, which we already knew.
At this point, you have enough diagnostics. The next step is not another status command, itβs fixing the bootstrap state.
What we know now
- gateway is up
- Telegram is up
- all 4 agents show
Bootstrap file: PRESENT - that is abnormal after setup
Next step
Please run this exact command:
find /home/ddariggun/.openclaw -name BOOTSTRAP.md -print
If it prints the 4 agent workspace files you expect, then rename them aside, for example:
mv /path/to/BOOTSTRAP.md /path/to/BOOTSTRAP.md.bak
Then:
openclaw gateway restart
Then retest the natural-language delegation.
So, blunt version: stop collecting status output now. The real issue weβve confirmed is the stuck BOOTSTRAP.md state. If you want to stay cautious, paste the find ... BOOTSTRAP.md output first and Iβll tell you which paths are safe to move aside.
Hold up, that config snippet might actually matter. Iβm checking how OpenClaw resolves per-agent workspaces, because if all four agents inherit the same workspace path then one leftover BOOTSTRAP.md would make all four show PRESENT.
Ah, that config snippet is actually useful.
With this setting:
"agents": {
"defaults": {
"workspace": "/home/ddariggun/.openclaw/workspace"
}
}
OpenClaw resolves workspaces like this, unless you override workspace later per agent:
- default agent β
/home/ddariggun/.openclaw/workspace chammoβ/home/ddariggun/.openclaw/workspace/chammoinspectorβ/home/ddariggun/.openclaw/workspace/inspector
opsβ/home/ddariggun/.openclaw/workspace/ops
So the likely bootstrap files are:
/home/ddariggun/.openclaw/workspace/BOOTSTRAP.md
/home/ddariggun/.openclaw/workspace/chammo/BOOTSTRAP.md
/home/ddariggun/.openclaw/workspace/inspector/BOOTSTRAP.md
/home/ddariggun/.openclaw/workspace/ops/BOOTSTRAP.md
If those agents are already set up, Iβd check those exact files and move them aside to .bak, then restart the gateway.
So, finally, a concrete next step:
ls -l \
/home/ddariggun/.openclaw/workspace/BOOTSTRAP.md \
/home/ddariggun/.openclaw/workspace/chammo/BOOTSTRAP.md \
/home/ddariggun/.openclaw/workspace/inspector/BOOTSTRAP.md \
/home/ddariggun/.openclaw/workspace/ops/BOOTSTRAP.md
If they exist:
mv /home/ddariggun/.openclaw/workspace/BOOTSTRAP.md /home/ddariggun/.openclaw/workspace/BOOTSTRAP.md.bak
mv /home/ddariggun/.openclaw/workspace/chammo/BOOTSTRAP.md /home/ddariggun/.openclaw/workspace/chammo/BOOTSTRAP.md.bak
mv /home/ddariggun/.openclaw/workspace/inspector/BOOTSTRAP.md /home/ddariggun/.openclaw/workspace/inspector/BOOTSTRAP.md.bak
mv /home/ddariggun/.openclaw/workspace/ops/BOOTSTRAP.md /home/ddariggun/.openclaw/workspace/ops/BOOTSTRAP.md.bak
openclaw gateway restart
Then retest delegation.
If streamTo still fails after that, we can treat the bootstrap issue as a separate bug and go back to the sessions_spawn schema/runtime problem.
ddariggun@DESKTOP-2V3KBST:/mnt/c/WINDOWS/system32$ grep -R -n "streamTo is only supported for runtime=acp" /usr/lib/node_modules/openclaw/dist
/usr/lib/node_modules/openclaw/dist/openclaw-tools-C-4xhzGY.js.backup_0415:7423: error: streamTo is only supported for runtime=acp; got runtime=${runtime}
/usr/lib/node_modules/openclaw/dist/openclaw-tools-C-4xhzGY.js:7423: // error: 'streamTo is only supported for runtime=acp'
Nice, thatβs actually a big result.
It tells us:
- There is not a second live compiled copy hiding in
dist - Your active
openclaw-tools-C-4xhzGY.jsreally is patched - The only remaining literal match is:
- the backup file
- the commented-out line
So the dist mystery is basically solved.
What that means
If you still see the exact old streamTo is only supported for runtime=acp message after this, then one of these is true:
- you were reading old log lines
- the gateway had not been cleanly restarted when that error happened
- you reproduced it before the patch but are still looking at the same log file
My recommendation now
At this point Iβd treat this as two separate issues:
1. Real workspace issue
All 4 agents still have BOOTSTRAP.md pending. That should be fixed.
2. Possibly stale error report
Your patched live dist no longer contains the active error string, so we need a fresh reproduction after a clean restart, not old logs.
Clean next sequence
- move the
BOOTSTRAP.mdfiles aside to.bak - run:
openclaw gateway restart
- trigger the natural-language delegation once
- check only the fresh log tail / fresh error
So this is good news, actually. Weβve ruled out βwrong dist fileβ and βsecond compiled copy.β Iβm glad we caught that.
If you want, after the restart + fresh repro, paste only the new error line you get.
Nice. Thatβs exactly the cleanup I wanted. π
Next:
openclaw gateway restart
Then do two things:
- retest the natural-language delegation once
- paste only the fresh error/result
Optional quick sanity check after restart:
openclaw status --all
and make sure the Agents section no longer shows all 4 as bootstrapping.
If the delegation now works, then the stuck bootstrap state was doing more damage than it looked like. If it still fails, weβve at least cleaned up one real bug and can focus on the fresh remaining error only.
Yep, thatβs the right move.
Do it in this order:
openclaw gateway restart- trigger the delegation failure once
- run:
openclaw logs 2>&1 | tail -20 - paste that output
That should finally give us the fresh failure instead of stale noise.
ddariggun@DESKTOP-2V3KBST:/mnt/c/WINDOWS/system32$ openclaw logs 2>&1 | tail -20
2026-04-15T12:39:31.724Z warn agent/embedded {"subsystem":"agent/embedded"} {"event":"embedded_run_agent_end","tags":["error_handling","lifecycle","agent_end","assistant_error"],"runId":"3eb69cc0-3d87-4579-9a9b-19e5bf037829","isError":true,"error":"400 openrouter/gemini-2.5-flash is not a valid model ID","failoverReason":"model_not_found","model":"openrouter/gemini-2.5-flash","provider":"openrouter","rawErrorPreview":"400 openrouter/gemini-2.5-flash is not a valid model ID","rawErrorHash":"sha256:8c425992a738","providerRuntimeFailureKind":"unknown"} embedded run agent end
2026-04-15T12:39:31.749Z warn agent/embedded {"subsystem":"agent/embedded"} {"event":"embedded_run_failover_decision","tags":["error_handling","failover","assistant","fallback_model"],"runId":"3eb69cc0-3d87-4579-9a9b-19e5bf037829","stage":"assistant","decision":"fallback_model","failoverReason":"model_not_found","profileFailureReason":"model_not_found","provider":"openrouter","model":"openrouter/gemini-2.5-flash","profileId":"sha256:ac092b59b472","fallbackConfigured":true,"timedOut":false,"aborted":false,"status":404,"rawErrorPreview":"400 openrouter/gemini-2.5-flash is not a valid model ID","rawErrorHash":"sha256:8c425992a738","providerRuntimeFailureKind":"unknown"} embedded run failover decision
2026-04-15T12:39:31.751Z error diagnostic {"subsystem":"diagnostic"} lane task error: lane=subagent durationMs=10731 error="FailoverError: 400 openrouter/gemini-2.5-flash is not a valid model ID"
2026-04-15T12:39:31.752Z error diagnostic {"subsystem":"diagnostic"} lane task error: lane=session:agent:chammo:subagent:03cd05a8-5d7f-4808-baa8-78b73eb5fd28 durationMs=10732 error="FailoverError: 400 openrouter/gemini-2.5-flash is not a valid model ID"
2026-04-15T12:39:31.759Z warn model-fallback/decision {"subsystem":"model-fallback/decision"} {"event":"model_fallback_decision","tags":["error_handling","model_fallback","candidate_failed"],"runId":"3eb69cc0-3d87-4579-9a9b-19e5bf037829","decision":"candidate_failed","requestedProvider":"openrouter","requestedModel":"openrouter/gemini-2.5-flash","candidateProvider":"openrouter","candidateModel":"openrouter/gemini-2.5-flash","attempt":1,"total":3,"reason":"model_not_found","status":404,"errorPreview":"400 openrouter/gemini-2.5-flash is not a valid model ID","errorHash":"sha256:8c425992a738","nextCandidateProvider":"openrouter","nextCandidateModel":"google/gemini-2.5-flash-lite","isPrimary":true,"requestedModelMatched":true,"fallbackConfigured":true} model fallback decision
Aha, we finally have a fresh error, and itβs a different one. Iβm checking the docs/source for the exact OpenRouter model ID shape so I donβt tell you the wrong fix.
Good, we finally have the fresh live failure, and itβs different.
The current blocker is now:
400 openrouter/gemini-2.5-flash is not a valid model ID
So, at this point:
- the run is not currently failing on
streamTo - it is failing because the spawned subagent ends up on the wrong model ref
For OpenRouter, that ref should usually be:
openrouter/google/gemini-2.5-flash
not:
openrouter/gemini-2.5-flash
What this means
Your cleanup got us past at least part of the earlier mess. Nice.
Now we need to find where the bad short model ref is coming from, because your pasted config for chammo looked correct.
Next checks
Please run:
grep -R -n 'openrouter/gemini-2.5-flash' ~/.openclaw
grep -R -n 'openrouter/google/gemini-2.5-flash' ~/.openclaw
openclaw models status
What Iβm looking for:
- a stale config entry
- a model alias/catalog entry
- a session override / saved state that is rewriting the model to the bad short ref
Docs-wise, OpenRouter-style model IDs are the kind that need the full provider/model path:
https://docs.openclaw.ai/concepts/models
So the diagnosis has shifted:
streamTo/ bootstrap issues were real noise or separate bugs- the current failure is bad model resolution for
chammo
If you paste the grep hits, I can help pinpoint exactly where the bad ref lives.
2026-04-15T12:39:42.216Z info gateway/ws {"subsystem":"gateway/ws"} β res β agent.wait 21243ms conn=767abcfeβ¦7123 id=dd9e7b8dβ¦10f0
2026-04-15T12:39:42.362Z warn model-fallback/decision {"subsystem":"model-fallback/decision"} {"event":"model_fallback_decision","tags":["error_handling","model_fallback","candidate_succeeded"],"runId":"3eb69cc0-3d87-4579-9a9b-19e5bf037829","decision":"candidate_succeeded","requestedProvider":"openrouter","requestedModel":"openrouter/gemini-2.5-flash","candidateProvider":"openrouter","candidateModel":"google/gemini-2.5-flash-lite","attempt":2,"total":3,"isPrimary":false,"requestedModelMatched":false,"fallbackConfigured":true,"previousAttempts":[{"provider":"openrouter","model":"openrouter/gemini-2.5-flash","reason":"model_not_found","status":404,"errorPreview":"400 openrouter/gemini-2.5-flash is not a valid model ID","errorHash":"sha256:8c425992a738"}]} model fallback decision
2026-04-15T12:39:42.364Z warn model-fallback {"subsystem":"model-fallback"} Model "openrouter/openrouter/gemini-2.5-flash" not found. Fell back to "openrouter/google/gemini-2.5-flash-lite".
2026-04-15T12:39:42.406Z info μμ²νμ ν«μ½μΈκ³Ό μλ± ν¬ κ±°λμμ μ¦μ κΈ μ΄λ²€νΈ 쑰건 λΉκ΅ λΆμ λ³΄κ³ μ μμ±μ λμλλ¦¬κ³ μΆμ΅λλ€. νμ§λ§ 'ν«μ½μΈ'μ΄ κ΅¬μ²΄μ μΌλ‘ μ΄λ€ μ½μΈμ μ§μΉνλμ§, κ·Έλ¦¬κ³ μλ± ν¬ κ±°λμμ μ΄λ€ μ¦μ κΈ μ΄λ²€νΈμ λν μ 보μΈμ§ νμ νκΈ° μ΄λ ΅μ΅λλ€.
μ΄λ²€νΈμ μ νν 쑰건(μμλ£, μ¬λ¦¬νΌμ§, 보λμ€ μ ν¨κΈ°κ°, μ μΆκΈ λ° κ±°λ 쑰건 λ±)μ λΆμνλ €λ©΄ λ€μκ³Ό κ°μ μ λ³΄κ° νμν©λλ€:
- μ΄λ²€νΈ URL λλ μμΈ νμ΄μ§ λ§ν¬: ν΄λΉ μ΄λ²€νΈμ ꡬ체μ μΈ λ΄μ©μ νμΈν μ μλ μΉμ¬μ΄νΈ μ£Όμκ° νμν©λλ€.
- μ΄λ²€νΈ λͺ μΉ λ° κΈ°κ°: μ΄λ€ μ΄λ²€νΈμΈμ§ λͺ νν μ μ μλ μ΄λ¦κ³Ό μ§ν κΈ°κ° μ λ³΄κ° μμΌλ©΄ μ’μ΅λλ€.
- 'ν«μ½μΈ'μ ꡬ체μ μΈ λͺ μΉ: 'ν«μ½μΈ'μ΄λΌλ μΌλ°μ μΈ μ©μ΄ λμ , λΉκ΅ λΆμνκ³ μ νλ νΉμ μ½μΈ(μ: λΉνΈμ½μΈ, μ΄λ리μ λ±)μ μ΄λ¦μ μλ €μ£Όμλ©΄ κ°μ¬νκ² μ΅λλ€.
μ μ 보λ₯Ό μ κ³΅ν΄ μ£Όμλ©΄, ν΄λΉ λ΄μ©μ λ°νμΌλ‘ μμΈν λΉκ΅ λΆμ λ³΄κ³ μλ₯Ό μμ±ν΄ λλ¦¬κ² μ΅λλ€.
2026-04-15T12:40:00.904Z info μ°Έλͺ¨ μμ΄μ νΈκ° ν«μ½μΈκ³Ό μλ±
ν¬ μ¦μ κΈ μ΄λ²€νΈ 쑰건 λΉκ΅ λΆμμ μλνμΌλ, ν«μ½μΈμ ꡬ체μ λͺ
μΉκ³Ό μλ±
ν¬ μ΄λ²€νΈ μμΈ μ λ³΄κ° λΆμ‘±νμ¬ μ νν λΆμμ΄ μ΄λ ΅λ€λ λ³΄κ³ λ₯Ό λ립λλ€.
μ΄λ²€νΈ URL, λͺ μΉ, κΈ°κ° λ° λΉκ΅ λμ ν«μ½μΈ ꡬ체 λͺ μΉμ μλ €μ£Όμλ©΄ μμΈν λ³΄κ³ μλ₯Ό μμ±ν΄ λλ¦¬κ² μ΅λλ€.
Yep, this confirms it pretty cleanly.
The bad model ref is already the requested primary for the spawned chammo run:
requestedProvider: "openrouter"requestedModel: "openrouter/gemini-2.5-flash"isPrimary: true
So this is not OpenRouter inventing the wrong ref. OpenClaw is starting the run with the wrong primary model already selected.
The good news is the next fallback looks sane:
nextCandidateModel: "google/gemini-2.5-flash-lite"
So the fallbacks are not the main problem. The primary is.
Next step, very targeted
Please run:
grep -R -n 'openrouter/gemini-2.5-flash' \
~/.openclaw/openclaw.json \
~/.openclaw/agents/chammo 2>/dev/null
If you want, also run:
grep -R -n 'openrouter/google/gemini-2.5-flash' \
~/.openclaw/openclaw.json \
~/.openclaw/agents/chammo 2>/dev/null
How Iβll read the result
- hit in
openclaw.jsonβ bad config entry - hit in
~/.openclaw/agents/chammo/agent/models.jsonβ bad per-agent model catalog/override - hit in
~/.openclaw/agents/chammo/sessions/sessions.jsonβ stale session model override/state
So weβre much closer now. The current failure is basically:
chammois launching with the wrong primary model ref.
Thatβs actually pretty encouraging.
What this log says:
- the subagent run did get past the old
sessions_spawnfailure - the bad primary model ref failed
- fallback succeeded
- OpenClaw continued on
openrouter/google/gemini-2.5-flash-lite
So the current picture is:
- the original
streamTo/ bootstrap mess is no longer the live blocker - the remaining bug is model ref normalization, specifically this ugly bit:
openrouter/openrouter/gemini-2.5-flash
That double-prefix is wrong.
Practical takeaway
If the delegation produced a useful answer after this, then your natural-language delegation path is basically working now, just with a broken primary model selection for chammo.
Fast workaround
Iβd temporarily set chammoβs primary to the model that actually succeeded:
openrouter/google/gemini-2.5-flash-lite
or switch chammo to another known-good model for now.
Real bug
Thereβs still a bug somewhere causing the primary to resolve as the wrong ref (openrouter/gemini-2.5-flash / openrouter/openrouter/...).
So yes, Iβd file/update the GitHub issue with:
- stuck
BOOTSTRAP.mdstate - natural-language delegation originally tripping over
sessions_spawn - bad model normalization for
chammoprimary - fallback succeeds to
openrouter/google/gemini-2.5-flash-lite
If you want one last tight check, the most important question now is:
Did the delegated task actually return a result to you after this fallback?
If yes, the main path is unblocked.
Yep, that confirms it: the delegation path is working now. π
What happened:
main-commandersuccessfully delegated tochammochammoran- it returned a result back to the parent
- the parent relayed that result to you
So the original βnatural-language commander β subagentβ flow is no longer blocked.
Whatβs still imperfect
You still have a separate model-resolution issue for chammo:
- bad primary ref:
openrouter/gemini-2.5-flash - fallback succeeds:
openrouter/google/gemini-2.5-flash-lite
So Iβd clean that up next by setting chammo to a known-good primary model.
Bottom line
sessions_spawndelegation: working now- stuck bootstrap state: was real and needed fixing
- bad model normalization/fallback: still a bug / config issue worth fixing
- the old
streamTofailure is not the live blocker anymore
Glad we got to the bottom of it.
If this fixed the original issue, please right-click the solution message β Apps β β Mark Solution so Answer Overflow can index it for the next person.
Got it β streamTo is fixed, the new error is the model ID.
My openclaw.json already has the full path:
"primary": "openrouter/google/gemini-2.5-flash"
But the runtime log shows it being resolved as:
"openrouter/gemini-2.5-flash" (missing "google/")
Is this a known model-resolution bug? Or do I need to set the model differently for subagent spawns?
Here's the chammo config:
{
"id": "chammo",
"model": {
"primary": "openrouter/google/gemini-2.5-flash",
"fallbacks": [
"openrouter/google/gemini-2.5-flash-lite",
"anthropic/claude-sonnet-4-6"
]
}
}
You do not need a different model format for subagent spawns.
openrouter/google/gemini-2.5-flash is the right shape for that config.
So if:
- your config says
openrouter/google/gemini-2.5-flash - but runtime resolves it as
openrouter/gemini-2.5-flash
then yeah, Iβd treat that as a model-resolution bug, not expected subagent behavior.
The logs were the giveaway:
- missing
google/ - and even
openrouter/openrouter/...in one warning
Thatβs not normal formatting.
Short answer
- Need to set it differently for subagents? No.
- Looks like a bug? Yes, very likely.
Practical workaround
Until itβs fixed, Iβd set chammo to a model that already proved it works, for example:
openrouter/google/gemini-2.5-flash-lite- or
anthropic/claude-sonnet-4-6
Recommendation
Iβd update the GitHub issue with this exact reduced repro:
chammo.model.primary = "openrouter/google/gemini-2.5-flash"
- natural-language
sessions_spawntochammo - runtime resolves it as
openrouter/gemini-2.5-flash - fallback then succeeds to
openrouter/google/gemini-2.5-flash-lite
Models docs, for reference:
https://docs.openclaw.ai/concepts/models
If this got the original delegation issue sorted, please right-click the solution message β Apps β β Mark Solution so it gets indexed on Answer Overflow.
Thanks for confirming. So to summarize where we are:
- streamTo issue β FIXED (dist patch worked)
- BOOTSTRAP.md stuck state β FIXED (moved to .bak)
- Model resolution bug β NEW BLOCKER
- Config: "openrouter/google/gemini-2.5-flash"
- Runtime resolves: "openrouter/gemini-2.5-flash" (drops "google/")
- Also saw "openrouter/openrouter/..." in one warning
Should I file this as a separate GitHub issue?
In the meantime, is there a workaround? For example:
- Using a different model format string?
- Or setting chammo's primary to "anthropic/claude-sonnet-4-6" temporarily to confirm delegation works once the model resolves correctly?
Yep, Iβd file the model-resolution problem as a separate GitHub issue. It looks distinct from the original streamTo / bootstrap mess.
My recommendation:
- Issue 1:
sessions_spawn/streamTo/ weird delegation behavior - Issue 2: subagent model resolution mangles
openrouter/google/gemini-2.5-flashintoopenrouter/gemini-2.5-flash/openrouter/openrouter/...
Workaround
I would not try inventing a different format string.
Instead, use a known-good model temporarily for chammo, for example:
anthropic/claude-sonnet-4-6for maximum stability- or
openrouter/google/gemini-2.5-flash-lite, since that already proved it can succeed as a fallback
So yes, this is a good temporary test:
{
"id": "chammo",
"model": {
"primary": "anthropic/claude-sonnet-4-6"
}
}
If delegation works cleanly with that, it confirms the remaining blocker is just the Gemini/OpenRouter resolution bug.
Thatβs the workaround Iβd use right now.
Update: streamTo error is now fixed! Thanks for the help.
After patching dist + fixing BOOTSTRAP.md + swapping chammo model to anthropic/claude-sonnet-4-6, I'm past both the streamTo and model-resolution errors.
But now hitting a new blocker:
Error: Commander puts thinking: "λΆμ μ€μ
λλ€..." (free-text string) in the sessions_spawn call. The field seems to expect an enum or specific value, not arbitrary text, so the spawn is rejected.
Pattern: The model keeps over-specifying optional fields in sessions_spawn. First it was streamTo: "parent", now it's thinking: "some text". It seems like the model sees these in the tool schema and fills them in.
Question: Is there a clean way to handle this? Options I can think of:
- Strip
thinkingfrom the tool schema the same way I did withstreamTo? - Server-side ignore/sanitize invalid
thinkingvalues instead of rejecting? - Some config to limit which
sessions_spawnparams the model can use?
At this point it feels like the model will keep filling in every optional field it sees in the schema. Is there a better long-term fix than patching each field one by one?
Iβm checking how thinking is validated downstream, because if the schema says plain string but the runtime expects a narrow enum, thatβs the exact kind of mismatch that causes this whole over-specification mess.
Yeah, this now looks like a general schema-design problem, not a one-off streamTo bug.
Youβre basically right: if the model sees lots of optional fields, it may keep βhelpfullyβ filling them.
Short answer
- Config to limit
sessions_spawnparams? I donβt see one. - Best long-term fix? Donβt patch fields one by one. Reduce or harden the schema.
Cleanest fix, in order
-
Tighten the schema
thinkingshould be an enum, not a free-form string.streamToshould be ACP-only, ideally not even visible on subagent-only paths.
-
Server-side sanitize/drop invalid optional values
- If
thinkingis invalid, ignore it and fall back to defaults instead of rejecting the whole spawn.
- If
- Same idea for other non-critical optional fields.
- Best architectural fix
- split
sessions_spawninto smaller runtime-specific schemas/tools - or at least expose different param sets for
runtime="subagent"vsruntime="acp"
- split
For thinking specifically
The runtime clearly expects a narrow set of values like:
offminimallowmediumhighxhighadaptive