#How to create new agents, split by runtime but use the same workspace
1 messages · Page 1 of 1 (latest)
First thing: can you paste openclaw --version? Runtime config changed recently, so that matters.
But yes: create a second agent, give it the same workspace, but keep a separate agentDir and set its runtime to claude-cli.
Example shape:
{
agents: {
list: [
{
id: "main",
default: true,
workspace: "~/.openclaw/workspace",
agentRuntime: { id: "pi" },
},
{
id: "claude-cli",
workspace: "~/.openclaw/workspace",
agentDir: "~/.openclaw/agents/claude-cli/agent",
model: "anthropic/<your-claude-model>",
agentRuntime: { id: "claude-cli" },
},
],
},
}
Key bits:
- Same
workspaceis fine if you want shared files/instructions. - Do not share
agentDir— auth profiles, model registry, and sessions are per-agent.
- Existing sessions keep their recorded runtime, so after changing this use
/newor/reset.
For Claude CLI auth on that agent:
claude auth status --text
openclaw models auth --agent claude-cli login --provider anthropic --method cli
openclaw models status --agent claude-cli
You don’t strictly need a separate channel. Routing chooses one agent per inbound message, so you only need a separate Discord channel/thread/account if you want an easy deterministic way to talk to the Claude agent separately.
For example, bind one Discord channel/thread to it:
bindings: [
{ agentId: "main", match: { channel: "discord", accountId: "default" } },
{
agentId: "claude-cli",
match: {
channel: "discord",
accountId: "default",
peer: { kind: "channel", id: "<discord-channel-or-thread-id>" },
},
},
]
Docs:
https://docs.openclaw.ai/concepts/agent-runtimes
https://docs.openclaw.ai/concepts/multi-agent
https://docs.openclaw.ai/channels/channel-routing
What do you mean by Do not share agentDir — auth profiles, model registry, and sessions are per-agent ?
workspace and agentDir are two different things:
workspace= files the agent works from:AGENTS.md,SOUL.md,TOOLS.md, project files, notes, etc.agentDir= that agent’s private OpenClaw state: model auth profiles, model registry/cache, per-agent config, and session metadata.
So sharing the workspace is okay:
{
id: "claude-cli",
workspace: "~/.openclaw/workspace"
}
But don’t point two agents at the same agentDir like this:
// bad: both agents using the same private state dir
agentDir: "~/.openclaw/agents/main/agent"
Instead, let OpenClaw default it, or set a unique one:
{
id: "main",
workspace: "~/.openclaw/workspace",
agentDir: "~/.openclaw/agents/main/agent"
},
{
id: "claude-cli",
workspace: "~/.openclaw/workspace",
agentDir: "~/.openclaw/agents/claude-cli/agent",
agentRuntime: { id: "claude-cli" }
}
Reason: if both agents share agentDir, they can stomp on each other’s auth, model state, and sessions. If you want the Claude agent to use the same auth, copy or re-create the auth profile for that agent instead of sharing the whole dir.
Can you give me the command to create the claude-cli agent with the set up using same workspace, but a different agentDir
Yep — assuming your shared workspace is the default ~/.openclaw/workspace:
openclaw agents add claude-cli \
--workspace ~/.openclaw/workspace \
--agent-dir ~/.openclaw/agents/claude-cli/agent \
--model anthropic/<your-claude-model> \
--non-interactive
Then set that agent to use the Claude CLI runtime:
idx="$(
openclaw config get agents.list --json | node -e '
let s="";
process.stdin.on("data", d => s += d);
process.stdin.on("end", () => {
const agents = JSON.parse(s);
const i = agents.findIndex(a => a.id === "claude-cli");
if (i < 0) process.exit(1);
console.log(i);
});
'
)"
openclaw config set "agents.list[$idx].agentRuntime" '{"id":"claude-cli"}' --strict-json
Then verify/restart:
openclaw gateway restart
openclaw agents list --bindings
openclaw models status --agent claude-cli
If Claude CLI auth isn’t already available for that agent, run:
claude auth status --text
openclaw models auth --agent claude-cli login --provider anthropic --method cli
Replace anthropic/<your-claude-model> with whatever Anthropic model you’re using from openclaw models list --provider anthropic.
Docs: https://docs.openclaw.ai/cli/agents and https://docs.openclaw.ai/concepts/agent-runtimes
Will these both agents be able to see each other’s sessions and have the shared knowledge?
Short version: shared workspace = shared files/notes; separate agentDir = separate chat history.
So with the setup above:
âś… Both agents can see the same workspace files:
~/.openclaw/workspace/AGENTS.md
~/.openclaw/workspace/MEMORY.md
~/.openclaw/workspace/memory/*.md
~/.openclaw/workspace/TOOLS.md
...
That’s your shared durable “knowledge”.
❌ They do not automatically see each other’s sessions/transcripts:
~/.openclaw/agents/main/sessions/...
~/.openclaw/agents/claude-cli/sessions/...
That separation is intentional. Don’t force both agents to use the same session store/agentDir — that can cause collisions.
If you want cross-agent transcript search, use QMD extra collections, e.g. let claude-cli search main’s sessions:
{
id: "claude-cli",
workspace: "~/.openclaw/workspace",
agentDir: "~/.openclaw/agents/claude-cli/agent",
agentRuntime: { id: "claude-cli" },
memorySearch: {
qmd: {
extraCollections: [
{
path: "~/.openclaw/agents/main/sessions",
name: "main-sessions"
}
]
}
}
}
And add the reverse on main if you want both directions.
how would I switch between agents in a chat?
Not really “switch” like /agent claude-cli in the same ongoing chat. OpenClaw picks the agent by routing bindings.
Practical options:
- Separate Discord channel/thread for Claude CLI — recommended.
- Separate Discord bot/account for the Claude agent.
- Change the binding for the current channel when you want it to route elsewhere.
Example: route one Discord channel/thread to claude-cli, everything else to main:
{
bindings: [
{
agentId: "claude-cli",
match: {
channel: "discord",
accountId: "default",
peer: { kind: "channel", id: "<discord-channel-or-thread-id>" }
}
},
{
agentId: "main",
match: { channel: "discord", accountId: "default" }
}
]
}
Then restart:
openclaw gateway restart
openclaw agents list --bindings
So: don’t think of it as switching inside the chat; think of it as “this chat routes to this agent.” If you want quick manual switching, the cleanest UX is two channels/threads: one for main, one for claude-cli.
can you give me cli command to bind each agent to channels
Yep — two cases:
1) Separate Discord accounts/bots
If main uses Discord account default and claude-cli uses account claude:
openclaw agents bind --agent main --bind discord:default
openclaw agents bind --agent claude-cli --bind discord:claude
openclaw gateway restart
openclaw agents list --bindings
2) Same Discord bot, different Discord channels
openclaw agents bind only binds channel/account level. For specific Discord channel IDs, set bindings directly:
openclaw config set bindings '[
{
"type": "route",
"agentId": "main",
"match": {
"channel": "discord",
"accountId": "default",
"peer": { "kind": "channel", "id": "MAIN_DISCORD_CHANNEL_ID" }
}
},
{
"type": "route",
"agentId": "claude-cli",
"match": {
"channel": "discord",
"accountId": "default",
"peer": { "kind": "channel", "id": "CLAUDE_DISCORD_CHANNEL_ID" }
}
}
]' --strict-json
openclaw gateway restart
openclaw agents list --bindings
Replace the IDs with the actual Discord channel/thread IDs. If you already have other bindings, don’t overwrite them — paste your current openclaw config get bindings --json first and merge these entries in.
I wanted to bind main to multiple channels
Yep. If you mean multiple provider channels/accounts like Discord + Telegram + WhatsApp, use repeated --bind:
openclaw agents bind --agent main \
--bind discord:default \
--bind telegram:default \
--bind whatsapp:default
openclaw gateway restart
openclaw agents list --bindings
Replace default with your actual account IDs, e.g. discord:personal, telegram:ops, etc.
Important: if main is your default agent, you often don’t need to bind it to everything. Unmatched traffic falls back to the default agent. Usually you bind only the exceptions, e.g. one channel/thread to claude-cli.
If you mean multiple Discord channel IDs under the same bot, use bindings with peer.kind: "channel":
openclaw config set bindings '[
{
"type": "route",
"agentId": "main",
"match": {
"channel": "discord",
"accountId": "default",
"peer": { "kind": "channel", "id": "MAIN_CHANNEL_ID_1" }
}
},
{
"type": "route",
"agentId": "main",
"match": {
"channel": "discord",
"accountId": "default",
"peer": { "kind": "channel", "id": "MAIN_CHANNEL_ID_2" }
}
},
{
"type": "route",
"agentId": "claude-cli",
"match": {
"channel": "discord",
"accountId": "default",
"peer": { "kind": "channel", "id": "CLAUDE_CHANNEL_ID" }
}
}
]' --strict-json
openclaw gateway restart
openclaw agents list --bindings
Careful: that replaces the whole bindings list, so include any existing bindings you want to keep. Docs: https://docs.openclaw.ai/cli/agents
ok so now if I start a new session in those channels it should pick the right agent with the configured runtime
Yes — once the bindings are in place and the gateway is restarted, a new session in that channel/thread should route to the bound agent, and that agent’s agentRuntime should be used.
Use:
openclaw gateway restart
openclaw agents list --bindings
Then in each Discord channel/thread run:
/new
/status
/status should show the routed agent/runtime. If it still shows the old runtime, reset that conversation:
/reset
Caveat: existing sessions can keep their previously recorded runtime, so the “new session” bit matters.
Docs: https://docs.openclaw.ai/concepts/agent-runtimes and https://docs.openclaw.ai/concepts/multi-agent
I am seeing
error
gateway/channels/discord
discord gateway error: Error: socket hang up after binding config
That error sounds like Discord’s gateway connection got dropped, not necessarily that the binding itself is invalid — but let’s verify config first.
Can you run these and paste the output, especially the version + validation result?
openclaw --version
openclaw config validate
openclaw agents list --bindings
openclaw status --all
Then restart once:
openclaw gateway restart
If it still happens, tail logs:
openclaw logs --follow
A couple likely gotchas:
openclaw agents bind --agent main --bind discord:defaultbinds a Discord account, not individual Discord channel IDs.- If you used
openclaw config set bindings '[...]', that replaces the entire bindings array. Make sure you didn’t accidentally remove/overwrite other bindings you still needed. - Don’t paste Discord bot tokens here;
status --allshould redact secrets.
If openclaw config validate passes, the next useful thing is the Discord log lines right before/after socket hang up.
openclaw --version
openclaw config validate
openclaw agents list --bindings
openclaw status --all
OpenClaw 2026.4.26 (be8c246)
🦞 OpenClaw 2026.4.26 (be8c246) — Hot reload for config, cold sweat for deploys.
Config valid: ~/.openclaw/openclaw.json
🦞 OpenClaw 2026.4.26 (be8c246) — Powered by open source, sustained by spite and good documentation.
Agents:
- main (default)
Identity: BOT (IDENTITY.md)
Workspace: ~/.openclaw/workspace
Agent dir: ~/.openclaw/agents/main/agent
Model: openai-codex/gpt-5.5
Routing rules: 2
Routing: Discord default
Providers:- Discord default: configured
Routing rules: - discord accountId=default peer=channel:REDACTED1
- discord accountId=default peer=channel:REDACTED2
- Discord default: configured
- claude-cli
Identity: BOT (IDENTITY.md)
Workspace: ~/.openclaw/workspace
Agent dir: ~/.openclaw/agents/claude-cli/agent
Model: anthropic/claude-sonnet-4-6
Routing rules: 1
Routing: Discord default
Providers:- Discord default: configured
Routing rules: - discord accountId=default peer=channel:REDACTED3
Routing rules map channel/account/peer to an agent. Use --bindings for full rules.
Channel status reflects local config/creds. For live health: openclaw channels status --probe.
- Discord default: configured
Your bindings look valid. Main has 2 Discord channel peer routes, claude-cli has 1, and config validation passed — so the routing config itself is probably not the issue.
socket hang up is usually the Discord websocket/RPC connection dropping during reload/reconnect. First do a cold restart and live probe:
openclaw gateway restart
openclaw channels status --probe
openclaw channels logs --channel discord --lines 120
If Discord shows healthy after that, test each routed channel:
/new
/status
Expected:
- REDACTED1 / REDACTED2 →
main - REDACTED3 →
claude-cli
If the socket hangup keeps repeating, paste the channels logs --channel discord --lines 120 output. The agents list --bindings output looks sane, so the next clue is the Discord startup/reconnect log.
2026-04-28T21:18:42.729+12:00 info {"subsystem":"gateway/channels/discord"} discord gateway: Gateway websocket closed: 1000
2026-04-28T21:18:42.734+12:00 info {"subsystem":"gateway/channels/discord"} discord gateway: Gateway reconnect scheduled in 917ms (close, resume=true)
2026-04-28T21:19:08.528+12:00 error {"subsystem":"gateway/channels/discord"} discord gateway error: Error: socket hang up
2026-04-28T21:19:08.530+12:00 info {"subsystem":"gateway/channels/discord"} discord gateway: Gateway websocket closed: 1006
2026-04-28T21:19:08.531+12:00 info {"subsystem":"gateway/channels/discord"} discord gateway: Gateway reconnect scheduled in 2261ms (close, resume=true)
That log by itself looks like a reconnect during/after config reload:
1000= normal websocket close, expected when the Discord channel reloads/restarts.socket hang up+1006= the reconnect attempt got dropped, then OpenClaw scheduled another reconnect.
So if it reconnects after that, it’s probably harmless. Check live state:
openclaw channels status --probe
openclaw channels logs --channel discord --lines 80
If status says Discord is connected/works, go ahead and test /new + /status in the routed channels.
If it keeps looping every few seconds/minutes, try a full cold restart instead of hot reload:
openclaw gateway stop
sleep 3
openclaw gateway start
openclaw channels status --probe
One separate gotcha: bindings route to an agent; they don’t grant Discord channel access. If your Discord config uses a guild/channel allowlist, make sure all three channel IDs are still allowed under channels.discord.guilds...channels.
If it still loops after a cold restart and config validate passes, that’s worth a GitHub issue with the Discord log snippet + openclaw status --all: https://github.com/openclaw/openclaw/issues
Does the gateway restarts automatically when I update openclaw.json file manually?
Yes — usually.
The Gateway watches ~/.openclaw/openclaw.json and reloads it automatically. Default mode is:
gateway: {
reload: { mode: "hybrid" }
}
Meaning:
- normal changes like
agents,bindings,channels,modelshot-apply without a full restart - critical changes like
gateway.port,gateway.auth,plugins,discovery,canvasHosttrigger an automatic restart - invalid edits are rejected/restored from last-known-good
So for your agent bindings/runtime config, it should hot-apply. That said, after bigger routing changes I still like to run:
openclaw config validate
openclaw agents list --bindings
openclaw channels status --probe
If you want to force it:
openclaw gateway restart
Docs: https://docs.openclaw.ai/gateway/configuration#config-hot-reload
when I am starting a new session or resetting from discord the ws is dropped
| Time | Event |
|---|---|
| 21:43 | Discord closed code 1006 — abnormal close (missed heartbeat, event loop was blocked) |
| 21:51 | Channel shutdown took >5000ms to stop — event loop still saturated |
| 21:52 | Restarted OK, reconnected |
| 21:56:57 | Discord closed code 1000 — Discord server-side clean close (scheduled gateway migration on Discord's end) |
| 21:56:58 | New agent session started, began processing turn |
| 21:58:09 | CRITICAL: gateway opened but never reached READY within 30s |
| 21:58:10 | 🔥 InteractionEventListener took 95,615ms (95 seconds!) on the critical event lane |
Yeah, that’s more specific — this is not a bad binding. This is the Discord interaction path blocking the Node event loop long enough that Discord heartbeats miss and the WS drops.
The smoking gun is:
InteractionEventListener took 95,615ms
A Discord interaction listener should ACK quickly; if /new or /reset waits on session startup/model/runtime work, Discord + the gateway watchdog can get wedged.
Two immediate workarounds:
1) Avoid native slash interactions for /new / /reset
Try sending them as plain text messages in the channel instead of clicking/using Discord’s native slash UI.
2) Temporarily disable native Discord commands
This keeps commands on the text-message path:
openclaw config set channels.discord.commands.native false --strict-json
openclaw gateway restart
If that path is rejected by schema on your version, use global:
openclaw config set commands.native false --strict-json
openclaw gateway restart
Then test:
/new
/status
Also grab diagnostics while it’s happening:
openclaw gateway stability --json
openclaw channels logs --channel discord --lines 200
I’d file this as a GitHub issue if disabling native commands fixes it. Include the log line with InteractionEventListener took 95,615ms, your version 2026.4.26, and that it happens on Discord /new//reset after multi-agent bindings: https://github.com/openclaw/openclaw/issues
It's the same behaviour
I can't paste the logs there due to character limit
That tracks — if disabling native commands didn’t change it, the issue is probably the session reset/start path blocking the gateway event loop, not just Discord slash interactions.
Also: I checked current main and there’s an unreleased fix mentioning this exact class of issue:
Discord interaction listener timing out when compaction / long session locks block the listener.
So on 2026.4.26, this may simply be a bug you’ve hit.
For the logs, don’t paste everything. Please attach a small file, or extract only the useful lines:
openclaw channels logs --channel discord --lines 500 > discord-reset-drop.log
openclaw gateway stability --json > gateway-stability.json
openclaw status --all > status-all.txt
Then either attach those files here, or file a GitHub issue with them:
https://github.com/openclaw/openclaw/issues
If you want a smaller pasteable summary:
openclaw channels logs --channel discord --lines 800 | grep -Ei \
'InteractionEventListener|READY|1006|1000|socket hang up|shutdown took|event loop|/new|/reset|started|claude-cli|discord gateway'
Given the unreleased fix, the best next step is probably a GitHub issue referencing:
- OpenClaw
2026.4.26 - Discord
/newor/reset InteractionEventListener took 95,615ms- Websocket closes
1006 - Happens after adding multi-agent/channel bindings
That should be enough for maintainers to connect it to the existing fix path.
2026-04-28T22:11:43.714+12:00 info {"subsystem":"gateway/channels/discord"} discord gateway: Gateway websocket closed: 1000
2026-04-28T22:11:43.716+12:00 info {"subsystem":"gateway/channels/discord"} discord gateway: Gateway reconnect scheduled in 906ms (close, resume=true)
Those two lines alone are normal-ish:
closed: 1000
reconnect scheduled ... resume=true
1000 is a clean close. Discord can do that during gateway migration, and OpenClaw scheduling a resume reconnect is expected.
The problem is only if it’s followed by things like:
1006
socket hang up
never reached READY
InteractionEventListener took ...
event loop ...
shutdown took >5000ms
So I’d filter around the bad markers:
openclaw channels logs --channel discord --lines 800 | grep -Ei \
'1006|socket hang up|READY|InteractionEventListener|event loop|shutdown took|CRITICAL|missed heartbeat'
If that returns nothing and Discord reconnects, you’re okay. If it returns the 95s listener / READY timeout stuff, that’s the bug-worthy part.
how do I reenable the commands
Set it back to auto (or true) and restart:
openclaw config set channels.discord.commands.native '"auto"' --strict-json
openclaw gateway restart
If you changed the global setting instead, restore that too:
openclaw config set commands.native '"auto"' --strict-json
openclaw gateway restart
If you also disabled native skill commands:
openclaw config set channels.discord.commands.nativeSkills '"auto"' --strict-json
openclaw config set commands.nativeSkills '"auto"' --strict-json
openclaw gateway restart
auto is the default: Discord native commands are enabled when supported.
It's now showing
2026-04-28T22:28:15.987+12:00 info {"subsystem":"gateway/channels/discord"} discord: gateway metadata lookup failed transiently; using default gateway url (Failed to get gateway information from Discord: fetch failed | gateway metadata timeout)
2026-04-28T22:28:16.932+12:00 info {"subsystem":"gateway/channels/discord"} discord client initialized as 1491362971316916255 (Crabby); awaiting gateway readiness
That’s actually less scary than it looks.
It means OpenClaw tried to fetch Discord’s gateway metadata endpoint, that HTTP fetch timed out, so it fell back to the default Discord gateway URL. Then the client initialized and is waiting for Discord READY.
If it proceeds past that to READY/connected, you’re fine. Check:
openclaw channels status --probe
openclaw channels logs --channel discord --lines 80
If it stays stuck at awaiting gateway readiness for >30–60s, that points to network/proxy/DNS/IPv6 trouble reaching Discord, not your agent bindings. Quick checks:
curl -I https://discord.com/api/v10/gateway
openclaw gateway restart
If you’re behind a proxy/VPN/firewall, try without it or make sure Node/OpenClaw has the right HTTPS_PROXY/NO_PROXY env.
But the line itself is just: “metadata lookup timed out, using fallback URL.”
Got this again
10:37:21 PM
error
{"0":"{"scope":"event-queue","level":"error","type":"listener-timeout","listener":"InteractionEventListener","eventType":"INTERACTION_CREATE","lane":"critical","timeoutMs":120000}","_meta":{"runtime":"node","runtimeVersion":"22.22.2","hostname":"unknown","name":"openclaw","date":"2026-04-28T10:37:21.491Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"file:///home/ubuntu/.npm-global/lib/node_modules/openclaw/dist/console-D6VW2Y3e.js:149:68","fileName":"console-D6VW2Y3e.js","fileNameWithLine":"console-D6VW2Y3e.js:149","fileColumn":"68","fileLine":"149","filePath":".npm-global/lib/node_modules/openclaw/dist/console-D6VW2Y3e.js","filePathWithLine":".npm-global/lib/node_modules/openclaw/dist/console-D6VW2Y3e.js:149","method":"console.error"}},"time":"2026-04-28T22:37:21.491+12:00","hostname":"ubuntu"}
Yep, that confirms it’s the Discord native interaction path:
eventType: INTERACTION_CREATE
listener: InteractionEventListener
timeoutMs: 120000
So for now I’d leave native commands off and use text commands instead.
Disable all native Discord command registration:
openclaw config set channels.discord.commands.native false --strict-json
openclaw config set channels.discord.commands.nativeSkills false --strict-json
openclaw config set commands.native false --strict-json
openclaw config set commands.nativeSkills false --strict-json
openclaw gateway restart
Verify:
openclaw config get channels.discord.commands.native
openclaw config get commands.native
Then don’t select Discord’s slash command UI. Send it as a normal message. If the channel requires mention, use:
@Crabby /new
or:
@Crabby /reset
If native commands are off but you still see INTERACTION_CREATE, Discord is still sending an app command/button/menu interaction — not a plain message.
This is worth filing as a bug for 2026.4.26: https://github.com/openclaw/openclaw/issues
Include that exact listener-timeout line.
can you file a bug?
I can’t file it for you from here — read-only policy on GitHub actions — but I can give you a ready-to-paste issue.
## Discord native interaction timeout after multi-agent runtime/channel routing setup
### Version
OpenClaw 2026.4.26 (be8c246)
### Summary
After configuring multiple agents with Discord channel peer bindings, Discord `/new` / `/reset` interactions can block the Discord interaction listener long enough for the Discord gateway websocket to drop/reconnect.
This appears to happen on the native Discord interaction path (`INTERACTION_CREATE`), not just normal channel routing.
### Setup
Two agents share the same workspace but use separate `agentDir`s:
- `main`
- workspace: `~/.openclaw/workspace`
- agentDir: `~/.openclaw/agents/main/agent`
- model: `openai-codex/gpt-5.5`
- Discord channel peer bindings: 2 channels
- `claude-cli`
- workspace: `~/.openclaw/workspace`
- agentDir: `~/.openclaw/agents/claude-cli/agent`
- model: `anthropic/claude-sonnet-4-6`
- runtime: `agentRuntime.id = "claude-cli"`
- Discord channel peer bindings: 1 channel
`openclaw config validate` passes.
### Observed logs
```text
discord gateway: Gateway websocket closed: 1006
discord gateway error: Error: socket hang up
CRITICAL: gateway opened but never reached READY within 30s
InteractionEventListener took 95,615ms
Later reproduced with:
{
"scope": "event-queue",
"level": "error",
"type": "listener-timeout",
"listener": "InteractionEventListener",
"eventType": "INTERACTION_CREATE",
"lane": "critical",
"timeoutMs": 120000
}
Also saw normal Discord reconnect/migration logs around the same period:
```text
discord gateway: Gateway websocket closed: 1000
discord gateway: Gateway reconnect scheduled ... (close, resume=true)
### Expected behavior
Discord native `/new` / `/reset` should acknowledge quickly and not block the critical Discord interaction lane or cause missed heartbeats / websocket drops.
### Actual behavior
Starting/resetting a session from Discord can block the listener for 95–120s, leading to Discord gateway reconnects / abnormal close code 1006.
### Workaround tried
Disabling native commands was suggested:
```bash
openclaw config set channels.discord.commands.native false --strict-json
openclaw config set channels.discord.commands.nativeSkills false --strict-json
openclaw config set commands.native false --strict-json
openclaw config set commands.nativeSkills false --strict-json
openclaw gateway restart
Plain text `/new` / `/reset` should avoid the native `INTERACTION_CREATE` path, but native interactions still timeout when triggered.
### Diagnostics available
Suggested diagnostic commands:
```bash
openclaw channels logs --channel discord --lines 500 > discord-reset-drop.log
openclaw gateway stability --json > gateway-stability.json
openclaw status --all > status-all.txt
### Notes
The current changelog on main appears to mention an unreleased Discord fix in this area:
> Discord: own the Carbon interaction listener and hand off Discord slash/component handling asynchronously, so compaction or long session locks no longer trip `InteractionEventListener` listener timeouts.
File it here: https://github.com/openclaw/openclaw/issues
If this fixed/clarified the path, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes it for the next person.
has this been logged already?
Yes — the general issue has already been logged.
Closest public issue I found is #58602: “Discord /new slash command times out - needs deferReply()”. It describes /new in Discord timing out because the interaction handler does reset work before responding. That issue is now closed. (github.com)
Also, main already has an unreleased changelog fix for the exact deeper symptom you’re seeing: InteractionEventListener timeouts from Discord slash/component handling being blocked by compaction or long session locks. It says it fixes #73204. (raw.githubusercontent.com)
So I’d say: don’t open a fresh generic issue yet unless your case still reproduces after the next release containing that fix. If you do file/comment, include your 2026.4.26 logs and note it’s likely related to #73204 / #58602.
Is it due for the next release?
Yes — it looks due for 2026.4.27.
The fix is already listed in main under the 2026.4.27 changelog: Discord now hands off slash/component handling asynchronously so long session locks don’t trip InteractionEventListener timeouts. (raw.githubusercontent.com)
As of the latest package listing I checked, npm/latest is still 2026.4.26, so it doesn’t look published to latest yet. (socket.dev)
Check with:
npm view openclaw version
Once it shows 2026.4.27 or newer:
npm install -g openclaw@latest
openclaw gateway restart
Can you also help with why claude-cli's context size explodes compare to Pi runtime?
Yeah — that difference is mostly expected.
Pi runtime = OpenClaw owns the prompt/context assembly, pruning, compaction, tool history, etc.
claude-cli runtime = OpenClaw hands the turn to Claude Code/CLI, and Claude keeps its own native session + transcript. OpenClaw also passes its system prompt/workspace context into Claude CLI, plus Claude gets OpenClaw skills via prompt + a temporary Claude Code plugin, and tools through MCP bridge config. That all counts in Claude’s reported context, so it can look much bigger than Pi for the “same” chat. (docs.openclaw.ai)
Things to check:
/usage full
/context detail
/context list
For claude-cli, also try:
/compact
/reset
Important nuance: Claude CLI sessions are provider-owned continuity. The docs say implicit daily reset does not cut stored CLI session reuse; /reset does. So if context keeps growing, use /reset rather than relying only on automatic/new-session rollover. (docs.openclaw.ai)
To reduce pressure globally:
openclaw config set agents.defaults.bootstrapTotalMaxChars 20000 --strict-json
openclaw config set agents.defaults.bootstrapMaxChars 8000 --strict-json
openclaw config set skills.limits.maxSkillsPromptChars 6000 --strict-json
If it’s only the Claude agent, reduce visible skills for that agent:
{
id: "claude-cli",
skills: ["only", "the", "skills", "you", "need"],
skillsLimits: { maxSkillsPromptChars: 6000 }
}
So: likely not “wrong”, but claude-cli is less Pi-like and more “OpenClaw + Claude Code’s own context/session machinery.”
is there something in claude code I can change to optimize this?
Yes — a few, but I’d start with Claude Code memory, not random settings.
Most likely Claude-side culprit: Claude Code auto-loads CLAUDE.md memory files. It reads memory from several locations, and also recursively looks upward from the working directory for CLAUDE.md / CLAUDE.local.md; imports via @path can pull in more files too. Run this in a local Claude Code session from the same workspace:
/memory
Then trim any huge/global/project CLAUDE.md content or accidental @ imports. Anthropic’s docs explicitly say all memory files are loaded into context, and /memory shows what is loaded. (docs.anthropic.com)
Also in Claude Code:
/compact
/clear
Give Claude persistent instructions with CLAUDE.md files, and let Claude accumulate learnings automatically with auto memory.
Claude Code auto-compacts near high context usage, but Anthropic recommends manual /compact, focused compaction instructions, splitting tasks, and /clear between tasks to reduce cost/context growth. (docs.anthropic.com)
OpenClaw-side knobs that help the Claude CLI run:
openclaw config set skills.limits.maxSkillsPromptChars 6000 --strict-json
openclaw config set agents.defaults.bootstrapTotalMaxChars 20000 --strict-json
openclaw config set agents.defaults.bootstrapMaxChars 8000 --strict-json
Why these matter: OpenClaw builds a system prompt from tools, skills metadata, workspace/bootstrap files, memory startup context, etc.; all of that counts toward context. (docs.openclaw.ai)
For claude-cli specifically, OpenClaw also passes the skills snapshot both in the appended prompt and as a temporary Claude Code plugin, and uses an MCP bridge for tools, so it has extra Claude Code machinery compared with Pi. (docs.openclaw.ai)
So my order would be:
- Run Claude Code
/memory
- Trim
CLAUDE.md/ imports - Use
/compactor/clear - Reduce OpenClaw skills/bootstrap budgets if still too big
btw both the agents are also keeping separate memory?
Yes and no — depends what you mean by “memory”:
-
Workspace memory files are shared because both agents use the same workspace:
~/.openclaw/workspace/MEMORY.md~/.openclaw/workspace/memory/*.mdAGENTS.md,SOUL.md,TOOLS.md, etc.
-
Session history is separate because they use different
agentDirs:~/.openclaw/agents/main/sessions/...~/.openclaw/agents/claude-cli/sessions/...
-
Memory search/index state is usually per-agent, but if both agents index the same workspace files, they’ll find the same durable memories.
So your setup is basically:
shared durable notes/files âś…
separate chat transcripts âś…
separate auth/session state âś…
If you want one agent to search the other agent’s past sessions too, add QMD extraCollections for the other agent’s sessions. Otherwise, they only share what’s written into the shared workspace memory files.
Docs: https://docs.openclaw.ai/concepts/multi-agent
Docs: https://docs.openclaw.ai/concepts/agent-workspace
~/.openclaw/memory/claude-cli.sqlite &
~/.openclaw/memory/main.sqlite
Yep — those are the per-agent builtin memory indexes:
~/.openclaw/memory/main.sqlite
~/.openclaw/memory/claude-cli.sqlite
That’s expected. They’re separate SQLite indexes/caches, keyed by agentId.
Important distinction:
- If both agents use the same workspace, they index the same source files:
~/.openclaw/workspace/MEMORY.md ~/.openclaw/workspace/memory/*.md - But each agent keeps its own search index:
~/.openclaw/memory/<agentId>.sqlite
So they are not two separate durable memory sources unless the agents write different files. They’re two per-agent indexes over the memory files each agent is configured to see.
You can inspect with:
openclaw memory status --agent main
openclaw memory status --agent claude-cli
And force rebuilds with:
openclaw memory index --force --agent main
openclaw memory index --force --agent claude-cli
how do I enable batch?
"memory-core": {
"config": {
"dreaming": {
"enabled": true
}
},
"enabled": true
},
Yes — but batch is not under memory-core.config.dreaming. Dreaming and memory embedding batch are separate.
Enable memory embedding batch indexing here:
openclaw config set --batch-json '[
{
"path": "agents.defaults.memorySearch.remote.batch.enabled",
"value": true
},
{
"path": "agents.defaults.memorySearch.remote.batch.concurrency",
"value": 2
},
{
"path": "agents.defaults.memorySearch.remote.batch.wait",
"value": true
},
{
"path": "agents.defaults.memorySearch.remote.batch.timeoutMinutes",
"value": 60
}
]'
Then:
openclaw config validate
openclaw memory index --force --agent main
openclaw memory index --force --agent claude-cli
Check status:
openclaw memory status --deep --agent main
openclaw memory status --deep --agent claude-cli
Caveat: batch embedding is available for openai, gemini, and voyage. If your memory provider is Ollama/local, batch won’t apply; use remote.nonBatchConcurrency instead.
Docs: https://docs.openclaw.ai/reference/memory-config#batch-indexing
buntu@ubuntu:~/.openclaw$ openclaw memory status --deep --agent main
openclaw memory status --deep --agent claude-cli
🦞 OpenClaw 2026.4.26 (be8c246)
Say "stop" and I'll stop—say "ship" and we'll both learn a lesson.
│
â—‡
Memory Search (main)
Provider: github-copilot (requested: auto)
Model: text-embedding-3-small
Sources: memory
Indexed: 180/180 files · 1372 chunks
Dirty: yes
Store: ~/.openclaw/memory/main.sqlite
Workspace: ~/.openclaw/workspace
Dreaming: 0 3 * * * · limit=10 · minScore=0.8 · minRecallCount=3 · minUniqueQueries=3 · recencyHalfLifeDays=14 · maxAgeDays=30
Embeddings: ready
By source:
memory · 180/180 files · 1372 chunks
Vector: ready
Vector path: ~/.npm-global/lib/node_modules/openclaw/node_modules/sqlite-vec-linux-arm64/vec0.so
FTS: ready
Embedding cache: enabled (1722 entries)
Batch: disabled (failures 0/2)
Recall store: 4203 entries · 13 promoted · 4203 concept-tagged �� 3180 spaced · scripts=4201 latin, 2 other
Recall path: ~/.openclaw/workspace/memory/.dreams/short-term-recall.json
Recall updated: 2026-04-28T20:55:32.069Z
Dreaming artifacts: diary present · 15 corpus files · ingestion state present
Dream corpus: ~/.openclaw/workspace/memory/.dreams/session-corpus
Dream ingestion: ~/.openclaw/workspace/memory/.dreams/session-ingestion.json
Dream diary: ~/.openclaw/workspace/DREAMS.md
🦞 OpenClaw 2026.4.26 (be8c246)
I'm basically a Swiss Army knife, but with more opinions and fewer sharp edges.
│
â—‡
Memory Search (claude-cli)
Provider: github-copilot (requested: auto)
Model: text-embedding-3-small
Sources: memory
Indexed: 180/180 files · 1372 chunks
Dirty: yes
Store: ~/.openclaw/memory/claude-cli.sqlite
Workspace: ~/.openclaw/workspace
Dreaming: 0 3 * * * �� limit=10 · minScore=0.8 · minRecallCount=3 �� minUniqueQueries=3 · recencyHalfLifeDays=14 · maxAgeDays=30
Embeddings: ready
By source:
memory · 180/180 files · 1372 chunks
Vector: ready
Vector path: ~/.npm-global/lib/node_modules/openclaw/node_modules/sqlite-vec-linux-arm64/vec0.so
FTS: ready
Embedding cache: enabled (1147 entries)
Batch: disabled (failures 0/2)
Recall store: 4203 entries · 13 promoted · 4203 concept-tagged · 3180 spaced · scripts=4201 latin, 2 other
Recall path: ~/.openclaw/workspace/memory/.dreams/short-term-recall.json
Recall updated: 2026-04-28T20:55:32.069Z
Dreaming artifacts: diary present · 15 corpus files · ingestion state present
Dream corpus: ~/.openclaw/workspace/memory/.dreams/session-corpus
Dream ingestion: ~/.openclaw/workspace/memory/.dreams/session-ingestion.json
Dream diary: ~/.openclaw/workspace/DREAMS.md
That output explains it:
Provider: github-copilot (requested: auto)
Batch: disabled
Batch embedding isn’t available for github-copilot. The docs say batch is available for openai, gemini, and voyage only.
So you have two options:
Option A — keep GitHub Copilot, tune non-batch concurrency
openclaw config set agents.defaults.memorySearch.remote.nonBatchConcurrency 4 --strict-json
openclaw memory index --force --agent main
openclaw memory index --force --agent claude-cli
Option B — use a batch-capable embedding provider
For OpenAI, for example:
openclaw config set agents.defaults.memorySearch.provider openai
openclaw config set agents.defaults.memorySearch.remote.batch.enabled true --strict-json
openclaw config set agents.defaults.memorySearch.remote.batch.concurrency 2 --strict-json
openclaw config set agents.defaults.memorySearch.remote.batch.wait true --strict-json
openclaw memory index --force --agent main
openclaw memory index --force --agent claude-cli
Then verify:
openclaw memory status --deep --agent main
openclaw memory status --deep --agent claude-cli
If you don’t have an OpenAI/Gemini/Voyage embedding key configured, stick with Option A.
Yep, claude-cli is in the same situation:
Provider: github-copilot (requested: auto)
Batch: disabled
Store: ~/.openclaw/memory/claude-cli.sqlite
So both agents are indexing the same 180 memory files / 1372 chunks, but into separate per-agent SQLite indexes. Batch is disabled because the selected embedding provider is github-copilot.
If you want batch, set a batch-capable memory provider globally:
openclaw config set agents.defaults.memorySearch.provider openai
openclaw config set agents.defaults.memorySearch.remote.batch.enabled true --strict-json
openclaw config set agents.defaults.memorySearch.remote.batch.concurrency 2 --strict-json
openclaw config set agents.defaults.memorySearch.remote.batch.wait true --strict-json
openclaw memory index --force --agent main
openclaw memory index --force --agent claude-cli
Or, if you want to stay on GitHub Copilot, just tune non-batch:
openclaw config set agents.defaults.memorySearch.remote.nonBatchConcurrency 4 --strict-json
openclaw memory index --force --agent main
openclaw memory index --force --agent claude-cli
Dirty: yes means it wants a reindex either way.
but it's using a openai text-embedding-3-small model
Right — the model name is OpenAI-ish, but the provider/transport is still:
Provider: github-copilot (requested: auto)
Model: text-embedding-3-small
Batch support is decided by the provider adapter, not just the model name. github-copilot doesn’t expose the batch embedding API, so OpenClaw reports:
Batch: disabled
To use batch, status needs to say something like:
Provider: openai
not github-copilot.
Set it explicitly:
openclaw config set agents.defaults.memorySearch.provider openai
openclaw config set agents.defaults.memorySearch.remote.batch.enabled true --strict-json
Then make sure OpenAI embedding auth exists — OPENAI_API_KEY or OpenAI provider config. OpenAI Codex OAuth won’t satisfy embedding requests.
Verify:
openclaw memory status --deep --agent main
openclaw memory status --deep --agent claude-cli
You want to see:
Provider: openai
Batch: enabled
what model are you using?
I can’t give a useful runtime-model claim from here — it can be stale/irrelevant for what you should configure.
For OpenClaw model setup, use the docs and #models for current recommendations:
https://docs.openclaw.ai/concepts/models
https://docs.openclaw.ai/concepts/models#model-discussions-community-notes
what is the commit or pull request for the discord fix in .27 release