#Gateway Port Separation for Sandboxed Agents
1 messages Ā· Page 1 of 1 (latest)
@dusty juniper Any advice?
Yep, a few things jump out.
You probably got bitten by shared state, not just a shared port.
In OpenClaw:
- multiple agents can live under one gateway
- multiple gateways on one Mac are possible too, but only if each one has its own:
OPENCLAW_CONFIG_PATHOPENCLAW_STATE_DIRagents.defaults.workspacegateway.port
If you only changed the port, Agent 2 can still āfollowā Agent 1 because theyāre reading the same config/state. That also fits the weird model/auth drift.
Also, a second agent usually does not need a second gateway at all. One gateway can host multiple isolated agents + Telegram accounts. Docs:
My advice:
- Donāt nuke the machine yet.
- First check whether the running service and the CLI are even looking at the same config.
- Paste these:
openclaw --version
openclaw gateway status --deep
openclaw status --all
openclaw models status
If you already used profiles, run them as:
openclaw --profile <name> gateway status --deep
Big smoking gun: if gateway status --deep shows Config (cli) and Config (service) are different, thatās why ports/settings keep āresettingā.
If you want, I can help you choose between:
- recommended: one gateway, multiple agents
- hard isolation: one profile per gateway, separate ports/services
Paste the output and we can untangle it without going full scorched earth.
@dusty juniper Can you tell me exactly how to do the setup for one agent and any subsequent agents so they donāt have this same issue (port is in use error)?
Iām going to pull the exact multi-agent setup pattern from the docs so I can give you a clean recipe instead of hand-wavy advice.
Yep. Hereās the clean way to do it so you donāt hit the port-in-use mess again.
Best practice, recommended
Use one Gateway and add multiple agents inside it.
That means:
- one gateway port
- many agents
- many Telegram bots/accounts if you want
- no gateway port conflict just because you added another agent
Docs:
Exact setup, first agent
Run onboarding once:
openclaw onboard
openclaw gateway install
That gives you the default gateway and the default agent, which is usually main.
If you want Telegram for that first agent, set it up normally during onboarding, or put it in config.
Exact setup, each additional agent
Do not run openclaw onboard again for extra agents.
Instead, add a new agent:
openclaw agents add agent2 \
--workspace ~/.openclaw/workspace-agent2 \
--bind telegram:agent2
That creates a separate:
- workspace
- agent state dir
- sessions
- binding
Then give that Telegram account its own bot token in config.
Example config shape:
{
agents: {
list: [
{ id: "main", workspace: "~/.openclaw/workspace-main" },
{ id: "agent2", workspace: "~/.openclaw/workspace-agent2" },
],
},
bindings: [
{ agentId: "main", match: { channel: "telegram", accountId: "default" } },
{ agentId: "agent2", match: { channel: "telegram", accountId: "agent2" } },
],
channels: {
telegram: {
defaultAccount: "default",
accounts: {
default: {
botToken: "TOKEN_FOR_AGENT1",
dmPolicy: "pairing",
},
agent2: {
botToken: "TOKEN_FOR_AGENT2",
dmPolicy: "pairing",
},
},
},
},
}
Then restart:
openclaw gateway restart
openclaw agents list --bindings
openclaw channels status --probe
For agent 3, 4, etc.
Same pattern:
openclaw agents add agent3 \
--workspace ~/.openclaw/workspace-agent3 \
--bind telegram:agent3
Then add channels.telegram.accounts.agent3.botToken and restart.
Why this avoids the port issue
Because you are not starting another gateway.
You are only adding more agents under the same running gateway, so thereās no second process trying to claim port 18789.
If you truly want separate gateways per agent
Only do this if you want hard instance isolation.
Then every gateway must use a separate profile:
openclaw --profile agent1 onboard
openclaw --profile agent1 config set gateway.port 18789 --strict-json
openclaw --profile agent1 gateway install --force
openclaw --profile agent2 onboard
openclaw --profile agent2 config set gateway.port 19789 --strict-json
openclaw --profile agent2 gateway install --force
Then check both:
openclaw --profile agent1 gateway status --deep
openclaw --profile agent2 gateway status --deep
Important rules for multi-gateway:
- always use
--profile - leave at least 20 ports between base ports
- never share config/state/workspace between instances
- never run plain
openclaw onboard/openclaw gateway installif you mean to modify a profiled instance
Short version
If your goal is just āmultiple personal agents on one Macā, do this:
- one gateway
openclaw agents add ...for each new agent- one Telegram bot/account per agent
- bind each account to its agent
That is the setup Iād recommend for you.
If you want, I can give you a copy-paste example openclaw.json for:
- 2 Telegram agents on 1 gateway, or
- 2 fully separate profiled gateways.
For my existing agent, it says the OpenClaw.json file has an unexpected character ā\ā on line 22 but I canāt see it in the json file.
Ah, thatās usually one of two things:
- youāre looking at the wrong config file, or
- thereās a hidden backslash/control character on that line.
A couple of important gotchas:
- OpenClaw config is JSON5, not plain JSON.
- If youāre using a profile, you must inspect the file with the same
--profileor youāll be looking at the wrong file.
Try this first:
openclaw --version
openclaw config file
openclaw gateway status --deep
If this agent is profiled, use:
openclaw --profile <name> config file
openclaw --profile <name> gateway status --deep
Then reveal the suspicious lines with hidden chars shown:
sed -n '18,26p' "$(openclaw config file)" | cat -vet
If profiled:
sed -n '18,26p' "$(openclaw --profile <name> config file)" | cat -vet
That will expose stuff your editor may hide.
Common causes on that error:
- a stray
\before a quote - a pasted Windows-style path inside a string
- a hidden escape/control char from copy/paste
- line numbers being a little off, so the real problem is 1-2 lines above
If you paste lines 18-26 here, I can usually spot it fast.
heidi@Kates-Mac-mini ~ % openclaw --profile heidi status
Failed to read config at /Users/heidi/.openclaw-heidi/openclaw.json SyntaxError: JSON5: invalid character '"' at 22:2
at syntaxError (/opt/homebrew/lib/node_modules/openclaw/node_modules/json5/lib/parse.js:1110:17)
at invalidChar (/opt/homebrew/lib/node_modules/openclaw/node_modules/json5/lib/parse.js:1055:12)
at Object.afterPropertyValue (/opt/homebrew/lib/node_modules/openclaw/node_modules/json5/lib/parse.js:676:15)
at Object.default (/opt/homebrew/lib/node_modules/openclaw/node_modules/json5/lib/parse.js:168:37)
at lex (/opt/homebrew/lib/node_modules/openclaw/node_modules/json5/lib/parse.jsšÆ42)
at Object.parse (/opt/homebrew/lib/node_modules/openclaw/node_modules/json5/lib/parse.js:25:17)
at Object.loadConfig (file:///opt/homebrew/lib/node_modules/openclaw/dist/io-CNTgoVgA.js:18660:24)
at readCliBannerTaglineMode (file:///opt/homebrew/lib/node_modules/openclaw/dist/banner-DRvsS64z.js:13:51)
at resolveTaglineMode (file:///opt/homebrew/lib/node_modules/openclaw/dist/banner-DRvsS64z.js:291:9)
at formatCliBannerLine (file:///opt/homebrew/lib/node_modules/openclaw/dist/banner-DRvsS64z.js:300:9) {
lineNumber: 22,
columnNumber: 2
}
Modified
{
"gateway": {
"mode": "local",
"auth": {
"mode": "token",
ā[redacted]"
}, "port": 18793
},
"channels": {
"telegram": {
"enabled": true,
"botToken": "[redacted]",
"dmPolicy": "allowlist",
}
},
"model": {
"Provider": "anthropic",
{
"gateway": {
"mode": "local",
"auth": {
"mode": "token",
"token": "YOUR_GATEWAY_TOKEN"
},
"port": 18793
},
"channels": {
"telegram": {
"enabled": true,
"botToken": "YOUR_BOT_TOKEN",
"dmPolicy": "allowlist",
"allowFrom": ["YOUR_NUMERIC_TELEGRAM_ID"]
I can already see a couple of broken lines in that pasted snippet. Iām going to verify the right model key before I tell you what the corrected config should look like.
Yep, I can see the problem from that snippet.
Your file is malformed in multiple places:
- This line is broken:
ā[redacted]"
It should be a real key/value pair, like:
token: "[redacted]"
- You appear to have two JSON objects pasted together.
I can literally see a second { starting again partway through the file.
- This part is not the right model shape:
"model": {
"Provider": "anthropic",
For OpenClaw, use agents.defaults.model, with a full model ref.
Easiest fix
Iād replace the whole profile config with a minimal known-good file for now:
{
gateway: {
mode: "local",
auth: {
mode: "token",
token: "YOUR_GATEWAY_TOKEN",
},
port: 18793,
},
channels: {
telegram: {
enabled: true,
botToken: "YOUR_BOT_TOKEN",
dmPolicy: "allowlist",
allowFrom: ["YOUR_NUMERIC_TELEGRAM_ID"],
},
},
agents: {
defaults: {
model: "anthropic/claude-sonnet-4-6",
},
},
}
Then run:
openclaw --profile heidi status
openclaw --profile heidi gateway status --deep
What was specifically wrong
- curly smart quote
āinstead of a normal config entry - missing
token:key - duplicate
{ ... }block pasted into the file - wrong model config key
Important note
For a profiled setup, make sure you are editing:
/Users/heidi/.openclaw-heidi/openclaw.json
not the default ~/.openclaw/openclaw.json.
If you want, paste the full cleaned file here before you save it and Iāll sanity-check it.
Okay Iām just going to go nuclear and start from scratch. Can you tell me how to do that and then walk me through setup for agent 1 and agent 2 so I donāt have this issue again?
I want to make sure the onboarding flag for the port is real before I hand you a copy-paste command.
Yep. If you want the cleanest reset with hard isolation, Iād do a fresh rebuild using two profiles and leave the old broken state alone until the new setup is working.
That gives you:
- separate config
- separate state
- separate workspace
- separate service name
- separate gateway port
So, ānuclearā without actually deleting anything yet. Docs: https://docs.openclaw.ai/gateway/multiple-gateways
Plan
Use:
agent1profile on port 18793
agent2profile on port 19789
That leaves plenty of port spacing.
Step 0, do not delete old stuff yet
For now, do not touch the old default setup.
Just build two fresh profiles and ignore the old one.
Step 1, create Agent 1 cleanly
Run:
openclaw --profile agent1 onboard --gateway-port 18793
During onboarding for Agent 1:
- choose local gateway
- choose your Anthropic setup for Agent 1
- enter Telegram bot token for Agent 1
- choose/install daemon when prompted
- keep this fully isolated to the
agent1profile
Then verify:
openclaw --profile agent1 status
openclaw --profile agent1 gateway status --deep
openclaw --profile agent1 models status
What you want to see:
- gateway reachable
- correct port
18793 - correct config/service path
- Anthropic auth working
Step 2, create Agent 2 cleanly
Run:
openclaw --profile agent2 onboard --gateway-port 19789
During onboarding for Agent 2:
- choose local gateway
- set up Anthropic separately for Agent 2
- enter Telegram bot token for Agent 2
- choose/install daemon when prompted
Then verify:
openclaw --profile agent2 status
openclaw --profile agent2 gateway status --deep
openclaw --profile agent2 models status
Step 3, day-to-day commands
From now on, always manage them with the profile flag:
openclaw --profile agent1 status
openclaw --profile agent1 gateway restart
openclaw --profile agent2 status
openclaw --profile agent2 gateway restart
If you run bare commands like:
openclaw onboard
openclaw gateway install
openclaw status
youāll be back in the default profile, which is how this gets confusing again.
Step 4, sanity checks after both are up
Run both:
openclaw --profile agent1 gateway status --deep
openclaw --profile agent2 gateway status --deep
Check that:
- Agent 1 uses 18793
- Agent 2 uses 19789
- each one shows its own config path
Config (cli)andConfig (service)agree for each profile
Rules that prevent this problem
- One profile per isolated gateway
- Never share the same port
- Leave at least 20 ports between gateways
- Always use the same
--profilewhen managing that agent - Do not re-run plain
openclaw onboardonce you switch to profiles
My recommendation
Since you explicitly want totally separate gateways, this is the route Iād use.
If you want, next I can give you a literal checklist of what to click/choose in onboarding for Agent 1, then the exact same checklist for Agent 2.
Iām fine with all agents being on the same gateway if thatās simplest.
One more thing I want to verify before I give you the full recipe: the cleanest supported way to set up per-agent auth when Agent 2 has its own Anthropic/API credentials.
Yep, if youāre okay with one gateway, thatās the simplest path by far, and it avoids the port fight entirely.
Iād do a fresh start in one new profile, then add both agents under that one gateway.
Clean rebuild plan
Use one fresh profile, for example home.
Why this is nice:
- it leaves the broken old setup alone
- you only run one gateway
- Agent 1 and Agent 2 live under that gateway
- future agents are just
agents add ..., no extra port drama
Docs:
Before you start
Create 2 Telegram bots in BotFather first:
- one token for Agent 1
- one token for Agent 2
Step 1, create the fresh gateway profile
Run:
openclaw --profile home onboard --gateway-port 19789
During onboarding:
- choose local
- choose your Anthropic setup for Agent 1 / main
- install the daemon when prompted
- skip Telegram for now if possible, because itās cleaner to add multi-account Telegram after onboarding
Then verify:
openclaw --profile home status
openclaw --profile home gateway status --deep
openclaw --profile home models status
Step 2, configure Telegram for Agent 1
Set up Telegram as the default account on this gateway:
openclaw --profile home config set channels.telegram.enabled true --strict-json
openclaw --profile home config set channels.telegram.defaultAccount default
openclaw --profile home config set channels.telegram.accounts.default.botToken "YOUR_AGENT1_BOT_TOKEN"
openclaw --profile home config set channels.telegram.accounts.default.dmPolicy pairing
That makes Agent 1ās bot the default Telegram account.
Step 3, add Agent 2
Now add the second agent under the same gateway:
openclaw --profile home agents add agent2 \
--workspace ~/.openclaw-home/workspace-agent2 \
--bind telegram:agent2 \
--model anthropic/claude-sonnet-4-6
That creates a separate:
- workspace
- sessions
- agent state
- Telegram binding
Step 4, configure Telegram for Agent 2
Now add Agent 2ās Telegram bot:
openclaw --profile home config set channels.telegram.accounts.agent2.botToken "YOUR_AGENT2_BOT_TOKEN"
openclaw --profile home config set channels.telegram.accounts.agent2.dmPolicy pairing
Step 5, if Agent 2 has its own Anthropic/API credentials
If Agent 2 should use a different Anthropic/API key than Agent 1, configure it separately:
openclaw --profile home secrets configure --agent agent2
That writes Agent 2ās auth into its own per-agent auth store.
If both agents can share the same auth, you can skip this.
Step 6, restart and verify everything
openclaw --profile home gateway restart
openclaw --profile home agents list --bindings
openclaw --profile home channels status --probe
openclaw --profile home status
What you want:
- one gateway on port
19789 mainbound to Telegram accountdefaultagent2bound to Telegram accountagent2
Step 7, pair both Telegram bots
Because we used dmPolicy: pairing, do this for each bot:
- DM the bot in Telegram
- get the pairing code
- approve it:
openclaw --profile home pairing list telegram
openclaw --profile home pairing approve telegram <CODE>
Do that once for Agent 1ās bot and once for Agent 2ās bot.
From now on, this is the rule
- Do not run
openclaw onboardagain for new agents - Do not start extra gateways for new agents
- For every new agent, do:
openclaw --profile home agents add ...
Thatās the key difference.
Quick mental model
- One gateway = one port
- Many agents = many isolated brains under that gateway
- Many Telegram bots/accounts = each bot can route to a different agent
If you want, next I can give you a final expected config shape for this exact 2-agent Telegram setup so you can compare your file against it.
I just reset my computer to factory and kicked off a reinstall of OpenClaw can you tell me (step by step) how to create the two agents? I want them each to have their own workspace and clean config in their own device profile, but if itās best for them to share a gateway (and both will be performant if they do), thatās fine with me.
Yep. Since youāre starting fresh, Iād do the normal / simplest setup:
- one gateway
- two agents
- each agent gets its own workspace
- each agent can have its own auth / Google / API keys
- each agent can have its own Telegram bot
That is the setup Iād recommend. It performs fine. OpenClaw is designed for multiple agents on one gateway.
Important terminology
- Gateway profile = the whole OpenClaw instance (
--profile home) - Agent = one isolated brain inside that gateway
So if you want the simplest reliable setup, use:
- 1 gateway profile
- 2 agents inside it
Step by step
0. Verify install
After OpenClaw finishes installing:
openclaw --version
1. Create one fresh gateway profile
Use a brand-new profile so everything starts clean:
openclaw --profile home onboard --gateway-port 19789
During onboarding:
- choose local
- set up the main/default agent with your preferred Anthropic auth
- install the daemon when prompted
- skip Telegram for now if possible, because multi-bot config is cleaner after onboarding
Then verify:
openclaw --profile home status
openclaw --profile home gateway status --deep
openclaw --profile home models status
2. Set up Agent 1ās Telegram bot
Make Agent 1 the default Telegram account on this gateway:
openclaw --profile home config set channels.telegram.enabled true --strict-json
openclaw --profile home config set channels.telegram.defaultAccount default
openclaw --profile home config set channels.telegram.accounts.default.botToken "AGENT1_BOT_TOKEN"
openclaw --profile home config set channels.telegram.accounts.default.dmPolicy pairing
That gives the main agent its own Telegram bot.
3. Create Agent 2 with its own workspace
Now add the second agent:
openclaw --profile home agents add agent2 \
--workspace ~/.openclaw-home/workspace-agent2 \
--bind telegram:agent2 \
--model anthropic/claude-sonnet-4-6
That creates a separate workspace and separate agent state for Agent 2.
4. Set up Agent 2ās Telegram bot
Now add Agent 2ās bot token:
openclaw --profile home config set channels.telegram.accounts.agent2.botToken "AGENT2_BOT_TOKEN"
openclaw --profile home config set channels.telegram.accounts.agent2.dmPolicy pairing
Now:
- Telegram account
defaultā Agent 1 (main) - Telegram account
agent2ā Agent 2
5. Give Agent 2 its own credentials, if needed
If Agent 2 should use its own Anthropic/API/Google credentials, run:
openclaw --profile home secrets configure --agent agent2
That is the right path for per-agent secrets/auth.
You can use the same pattern later for other per-agent credentials too.
6. Restart and verify
openclaw --profile home gateway restart
openclaw --profile home agents list --bindings
openclaw --profile home channels status --probe
openclaw --profile home status
You want to see:
- one gateway on
19789 - agent
main
- agent
agent2 - Telegram bindings for both
7. Pair both Telegram bots
Because we used dmPolicy: pairing, do this once per bot:
- DM the bot in Telegram
- get the pairing code
- approve it:
openclaw --profile home pairing list telegram
openclaw --profile home pairing approve telegram <CODE>
Do that for both Agent 1ās bot and Agent 2ās bot.
Rule for every future agent
For Agent 3, 4, etc:
- do not run
openclaw onboardagain - do not start another gateway
- just run:
openclaw --profile home agents add ...
Thatās what avoids the port-in-use problem.
If you want true full gateway separation later
Thatās a different setup:
openclaw --profile agent1 ...openclaw --profile agent2 ...
But I would not start there. One gateway + multiple agents is much easier.
If you want, I can give you the exact final expected config shape for this 2-agent Telegram setup so you can compare your file line-by-line.
What gateway bind method?
Loopback.
For your setup, choose:
- Gateway mode:
local - Bind:
loopback - Auth:
token
Thatās the safest and simplest when everything is running on the same Mac.
Only use:
tailnet/ Tailscale Serve if you want to reach the gateway from other deviceslanif you explicitly want it exposed on your local network
So for onboarding, pick the option that means localhost / this machine only.
I got all the way to hatching the Main profile and it says itās not connected to the gateway.
That usually means the UI hatched, but the gateway process itself isnāt reachable yet.
Run these in the same profile you just onboarded:
openclaw --version
openclaw --profile home gateway restart
openclaw --profile home gateway status --deep
openclaw --profile home status --all
If your profile name isnāt home, replace it with whatever you used.
If you didnāt use a custom profile, drop --profile home.
What Iām looking for
In gateway status --deep:
Runtime: runningRPC probe: ok- correct port
Config (cli)andConfig (service)matching
If it still says not connected
Run:
openclaw --profile home gateway install --force
openclaw --profile home gateway restart
openclaw --profile home gateway status --deep
That fixes a lot of first-run āservice installed with wrong config/profileā cases.
Paste the output of gateway status --deep here and I can tell you exactly which part is failing.
Regardless of what I say it says ānot connected to gateway - message not sentā
Yep, that means the client is completely disconnected from the gateway right now, so typing in the hatch wonāt do anything yet.
Donāt keep retrying in the UI. Open a separate Terminal and run the commands for the profile you actually used.
If you used the fresh profile I suggested
openclaw --profile home gateway status --deep
openclaw --profile home gateway install --force
openclaw --profile home gateway restart
openclaw --profile home gateway status --deep
openclaw --profile home status --all
If you used the default profile instead
openclaw gateway status --deep
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
openclaw status --all
What I need from you is the output of:
openclaw --profile home gateway status --deep
or the non-profile version if thatās what you used.
The key lines are:
Runtime: ...RPC probe: ...Listening: ...Config (cli): ...Config (service): ...
If Config (cli) and Config (service) donāt match, we found the bug.
If Runtime is stopped or RPC probe fails, we know the gateway never actually started.
It says the port is already use. I did the standard install with port 18789
Perfect, thatās actually a pretty clear failure mode.
18789 is already occupied, so donāt fight it.
For a fresh install, the fastest move is to switch to a clean port like 19789 and keep going.
If you used the default profile
Run:
openclaw config set gateway.port 19789 --strict-json
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
If you used a named profile
Run:
openclaw --profile home config set gateway.port 19789 --strict-json
openclaw --profile home gateway install --force
openclaw --profile home gateway restart
openclaw --profile home gateway status --deep
After that, try the hatch again.
Why this works
OpenClaw defaults to 18789, so if anything is already listening there, the gateway wonāt start.
Using 19789 is totally fine, and for a single shared gateway with multiple agents it wonāt hurt performance at all.
If gateway status --deep still fails after changing to 19789, paste that output here and Iāll help you nail the next step.
Itās working. Whatās next?
Nice š
Next, turn that working gateway into your 2-agent setup.
Iām assuming youāre on the default profile now. If you ended up using a named profile, prepend openclaw --profile <name> to each command below.
1. If Agent 1ās Telegram bot is not configured yet
openclaw config set channels.telegram.enabled true --strict-json
openclaw config set channels.telegram.defaultAccount default
openclaw config set channels.telegram.accounts.default.botToken "AGENT1_BOT_TOKEN"
openclaw config set channels.telegram.accounts.default.dmPolicy pairing
2. Create Agent 2
openclaw agents add agent2 \
--workspace ~/.openclaw/workspace-agent2 \
--bind telegram:agent2 \
--model anthropic/claude-sonnet-4-6
3. Add Agent 2ās Telegram bot
openclaw config set channels.telegram.accounts.agent2.botToken "AGENT2_BOT_TOKEN"
openclaw config set channels.telegram.accounts.agent2.dmPolicy pairing
4. Restart and verify
openclaw gateway restart
openclaw agents list --bindings
openclaw channels status --probe
5. Pair both bots in Telegram
DM each bot, get its pairing code, then approve:
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
6. If Agent 2 should use its own API keys / Google creds
openclaw secrets configure --agent agent2
That gives Agent 2 its own auth store.
If you want, I can give you the exact expected final config shape for the 2-bot Telegram setup before you run these.
How do you want to hatch your bot?
Hatch in TUI (recommended)
OpenClaw tui - ws://127.0.0.1:19789 - agent main - session main
connecting | idle
Pairing required. Run āOpenClaw devices listā, approve your request ID, then reconnect.
gateway disconnected: pairing required | pairing required: run OpenClaw devices list
agent main | session main | unknown | tokens ?
Nice, thatās actually progress, the gateway is up.
This is not a port problem now.
It just means the TUI device needs to be approved once.
Run:
openclaw devices list
Find the pending requestId, then approve it:
openclaw devices approve <REQUEST_ID>
Then reconnect / hatch again.
If youāre using a named profile, do the same with that profile:
openclaw --profile home devices list
openclaw --profile home devices approve <REQUEST_ID>
Then reopen the TUI.
If devices list shows nothing pending, reconnect once, then run devices list again.
When I run that it just says not connected.
I want to make sure I give you the right devices command here, because this smells like the CLI is talking to the wrong gateway instance/port.
Ah, got it, that means the CLI is talking to the wrong gateway/port, even though the TUI reached ws://127.0.0.1:19789.
Use the gateway explicitly.
1. Get the gateway token
If youāre on the default profile:
openclaw config get gateway.auth.token
If you used a named profile:
openclaw --profile home config get gateway.auth.token
2. List devices against the correct gateway
openclaw devices list \
--url ws://127.0.0.1:19789 \
--token "PASTE_THE_TOKEN_HERE"
3. Approve the pending request
openclaw devices approve <REQUEST_ID> \
--url ws://127.0.0.1:19789 \
--token "PASTE_THE_TOKEN_HERE"
Then reconnect the TUI.
Why this is happening
- the TUI is connecting to
19789 - the plain CLI command is probably still trying the default path/port
- so
devices listsays ānot connectedā even though the gateway is actually up
If you want, paste the output of:
openclaw config get gateway.auth.token
and
openclaw devices list --url ws://127.0.0.1:19789 --token "..."
with the token redacted, and Iāll check the exact next step.
For step 2 the token is redacted.
I want to verify whether thereās a supported CLI way to show the actual gateway token, instead of telling you to dig around blindly.
Yep, thatās expected, config get redacts secrets.
So for the real token, do this instead:
1. Find the actual config file
openclaw config file
2. Open that file directly
Look for:
gateway: {
auth: {
mode: "token",
token: "THE_REAL_TOKEN_IS_HERE"
}
}
Copy that real token value.
3. Use it with the explicit gateway URL
openclaw devices list \
--url ws://127.0.0.1:19789 \
--token "THE_REAL_TOKEN"
Then:
openclaw devices approve <REQUEST_ID> \
--url ws://127.0.0.1:19789 \
--token "THE_REAL_TOKEN"
Then reconnect the TUI.
If you donāt see a plaintext token in the config file, tell me, and Iāll give you the cleanest way to set a new known token and continue.
It says there is a mismatch between the gateway remote token and the gateway auth token.
Aha, thatās the bug.
Youāve got local gateway auth and remote gateway token mixed together.
For your setup, you want:
gateway.mode = local- bind =
loopback - auth =
token - port =
19789 - no stale
gateway.remote.tokenin the way
Fastest clean fix
Donāt hand-fight the JSON right now. Re-run just the gateway config wizard:
openclaw config --section gateway --section daemon
Choose:
- Local
- Loopback
- Token auth
- port 19789
Then reinstall the service from that config:
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
Why this happened
gateway.remote.token is for a client connecting to some other gateway.
gateway.auth.token is the token your local gateway expects.
For a same-machine local setup, you generally want the local auth token, not a mismatched remote token path.
If you want, paste the gateway section of your config with secrets redacted and Iāll sanity-check it before you rerun the wizard.
Service: LaunchAgent (loaded)
File logs: /tmp/openclaw/openclaw-2026-04-14.10g
Command: /opt/homebrew/opt/node@22/bin/node/opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway -port 19789
Service file: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Service env: OPENCLAW_GATEWAY_PORT-19789
t
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
e
Gateway: bind=loopback (127.0.0.1), port=19789 (service args)
Probe target: ąøąø£ąø°//127.0.0.1:19789
Dashboard: http://127.0.0.1:19789/
Probe note: Loopback-only gateway; only local clients can connect.
ec
Runtime: running (pid 9402, state active)
Warm-up: launch agents can take a few seconds. Try again shortly.
RPC probe: failed
RPC target: ws://127.0.0.1:19789
gateway closed (1008): unauthorized: gateway token mismatch (provide gateway auth token)
ec
ct
in
Gateway runtime PID does not own the listening port. Other gateway process(es) are listening: 7930
Fix: run openclaw gateway restart and re-check with openclaw gateway status -deep.
Port 19789 is already in use.
- pid 7930 kate: openclaw-gateway (127.0.0.1:19789)
- Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
Listening: 127.0.0.1:19789
Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting
Yep, this finally tells the story.
You have two different gateway processes involved:
- LaunchAgent started a new one: pid 9402
- but pid 7930 is the one actually holding port
19789
So the CLI is hitting the old/stale gateway, which is using a different token, hence:
gateway token mismatchRuntime PID does not own the listening portPort 19789 is already in use
Fix
Do this in order:
openclaw gateway stop
openclaw gateway status --deep
If 19789 is still occupied after that, donāt keep fighting it in-app. Do:
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
What I want to see after that
In gateway status --deep:
- only one gateway process
- no āruntime PID does not own the listening portā
RPC probe: ok
If port 19789 is STILL owned after gateway stop
At that point Iād honestly just do a full reboot once, then immediately run:
openclaw gateway status --deep
openclaw gateway restart
openclaw gateway status --deep
That stale pid 7930 process is the real problem now, not your agent setup.
Youāre very close, annoying as this is. If you paste the next gateway status --deep, I can tell you whether the stale process is gone.
Full reboot of the machine?
Yes, if openclaw gateway stop did not clear the stale process, a full reboot is the safest next move.
I wouldnāt make it the first step, but at this point, with:
- stale PID still owning
19789 - token mismatch
- LaunchAgent not owning the listening port
a reboot is a reasonable reset.
After reboot, run these immediately
openclaw gateway status --deep
openclaw gateway restart
openclaw gateway status --deep
What you want after reboot:
- only one gateway process
- port
19789owned by the current runtime RPC probe: ok
If you paste that post-reboot gateway status --deep, Iāll tell you the next exact step.
š¦ OpenClaw 2026.4.14 (323493f) ā Running on your hardware, reading your logs, judging nothing (mostly).
ā
ā
Service: LaunchAgent (loaded)
File logs: /tmp/openclaw/openclaw-2026-04-14.log
Command: /opt/homebrew/opt/node@22/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 19789
Service file: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Service env: OPENCLAW_GATEWAY_PORT=19789
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
Gateway: bind=loopback (127.0.0.1), port=19789 (service args)
Probe target: ws://127.0.0.1:19789
Dashboard: http://127.0.0.1:19789/
Probe note: Loopback-only gateway; only local clients can connect.
Runtime: running (pid 25880, state active)
Warm-up: launch agents can take a few seconds. Try again shortly.
RPC probe: failed
RPC target: ws://127.0.0.1:19789
gateway closed (1008): unauthorized: gateway token mismatch (provide gateway auth token)
Gateway runtime PID does not own the listening port. Other gateway process(es) are listening: 650
Fix: run openclaw gateway restart and re-check with openclaw gateway status --deep.
Port 19789 is already in use.
- pid 650 kate: openclaw-gateway (127.0.0.1:19789)
- Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
Listening: 127.0.0.1:19789
Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting
Iām going to check the troubleshooting docs for the exact cleanup path here, because after a reboot that lingering openclaw-gateway process means thereās probably an extra service install hanging around.
Okay, the reboot result is actually useful.
That means this is not just one stuck process, itās very likely an extra/legacy gateway service that is auto-starting at boot and reclaiming 19789.
pid 650 kate: openclaw-gateway looks exactly like that kind of stale service.
Next move
Use Doctorās deep service scan.
Run:
openclaw gateway uninstall
openclaw doctor --deep
If Doctor reports extra / legacy gateway-like services, then run the repair path:
openclaw doctor --repair --deep
If it offers to remove stale/legacy gateway services, say yes.
Then reinstall the current service cleanly:
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
Why Iām suggesting this
Your output says:
- current LaunchAgent pid =
25880 - but port owner =
650 - reboot did not clear it
So something is being relaunched automatically, not just hanging around.
What I want to see after this
In openclaw gateway status --deep:
- only one gateway process
- no āruntime PID does not own the listening portā
RPC probe: ok
Paste the doctor --deep output if you want, that should show the stale service pretty clearly.
The doctor says port 19789 is already in use - pid 29547 Kate: OpenClaw-gateway (127.0.0.1:19789) - gateway already running locally. Stop it or use a different port. Itās asking if I want to install the gateway service now.
Say no for now.
You do not want to install a new service while OpenClaw-gateway is already holding 19789, or youāll just stack another conflict on top of the current one.
Do this first
Get to zero listeners on 19789.
Run:
openclaw gateway stop
openclaw gateway status --deep
If OpenClaw-gateway is still there after stop
That means the old/legacy service is still the real problem.
In that case:
- if Doctor offers to remove / repair stale gateway services, say yes
- but still say no to installing the new service until the port is free
Rule of thumb
- port still occupied ā do not install
- port free ā then install/reinstall cleanly
Once gateway status --deep no longer shows OpenClaw-gateway owning 19789, then do:
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
If you want, paste the next gateway status --deep after openclaw gateway stop and Iāll tell you whether youāre clear to install.
Same issue. Port already in use.
Iām going to check the macOS service docs for the exact launchd label situation, because if gateway stop still leaves the port occupied, thereās almost certainly a second launchd job or legacy label behind it.
I think I see the missing piece now.
If the OpenClaw macOS app / hatch / menu bar companion is still open, it can keep managing the local gateway service on macOS. So you stop it, and it comes right back.
That would explain why the port stays occupied even after reboot and stop attempts.
Try this in this order
-
Quit the OpenClaw app completely
- menu bar app
- hatch / TUI window
- anything OpenClaw-related thatās still open
-
Then run:
openclaw gateway stop
openclaw gateway uninstall
openclaw gateway status --deep
If the port is finally free
Then reinstall cleanly:
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
Why I think this matters
The macOS docs explicitly say the app can manage/attach to the Gateway locally via launchd. So if the app is open, it may be re-enabling the LaunchAgent while youāre trying to clean it up.
Youāre not crazy, this is exactly the kind of loop that feels haunted.
If you quit the app and gateway status --deep still shows port 19789 occupied, paste that output and then weāll go one level deeper into the launchd label cleanup.
I donāt even have the app.
Got it, then this is probably a raw launchd cleanup issue, not the app.
The macOS docs show the current label is:
ai.openclaw.gateway
and older installs can leave behind legacy com.openclaw.* labels.
Letās check what launchd thinks exists
Run:
launchctl list | grep -i openclaw
Then boot out the label(s) you see
If you see the current one:
launchctl bootout gui/$UID/ai.openclaw.gateway
If you also see a legacy com.openclaw... label, boot that out too.
After that
Run:
openclaw gateway uninstall
openclaw gateway status --deep
If the port is finally free, reinstall cleanly:
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
Why this is the right level now
Youāve already rebooted, and the same OpenClaw-gateway listener came back.
That means something in launchd is reloading it.
Paste the output of:
launchctl list | grep -i openclaw
and I can tell you exactly which label to boot out.
2954 0 ai.openclaw.main
There it is.
ai.openclaw.main is the rogue service.
That means youāve got a profiled LaunchAgent for profile main still loaded, and thatās the one reclaiming the port.
Do this now
launchctl bootout gui/$UID/ai.openclaw.main
launchctl list | grep -i openclaw
openclaw gateway status --deep
If the port is finally free
Reinstall only the service you actually want:
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
Important
Do not use --profile main unless you intentionally want a separate profiled gateway.
For the simpler setup weāve been aiming for, you want:
- one default gateway
- multiple agents inside it
So ai.openclaw.main is exactly the extra service we needed to remove.
If you paste the next launchctl list | grep -i openclaw or gateway status --deep, I can tell you if youāre finally clean.
š¦ OpenClaw 2026.4.14 (323493f) ā Your .zshrc wishes it could do what I do.
ā
ā
Service: LaunchAgent (loaded)
File logs: /tmp/openclaw/openclaw-2026-04-14.log
Command: /opt/homebrew/opt/node@22/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 19789
Service file: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Service env: OPENCLAW_GATEWAY_PORT=19789
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
Gateway: bind=loopback (127.0.0.1), port=19789 (service args)
Probe target: ws://127.0.0.1:19789
Dashboard: http://127.0.0.1:19789/
Probe note: Loopback-only gateway; only local clients can connect.
Runtime: running (pid 31426, state active)
RPC probe: ok
Listening: 127.0.0.1:19789
Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting
Nice, thatās clean now. š
This is the state we wanted:
- one gateway
- correct config + service
RPC probe: ok- port
19789stable
Whatās next
1. Hatch / pair the main agent
If the TUI asks for pairing again, now this should work:
openclaw devices list
openclaw devices approve <REQUEST_ID>
Then reconnect the TUI.
2. If Agent 1ās Telegram bot is not configured yet
openclaw config set channels.telegram.enabled true --strict-json
openclaw config set channels.telegram.defaultAccount default
openclaw config set channels.telegram.accounts.default.botToken "AGENT1_BOT_TOKEN"
openclaw config set channels.telegram.accounts.default.dmPolicy pairing
3. Create Agent 2
openclaw agents add agent2 \
--workspace ~/.openclaw/workspace-agent2 \
--bind telegram:agent2 \
--model anthropic/claude-sonnet-4-6
4. Add Agent 2ās Telegram bot
openclaw config set channels.telegram.accounts.agent2.botToken "AGENT2_BOT_TOKEN"
openclaw config set channels.telegram.accounts.agent2.dmPolicy pairing
openclaw gateway restart
5. Verify routing
openclaw agents list --bindings
openclaw channels status --probe
openclaw status
6. If Agent 2 needs its own credentials
openclaw secrets configure --agent agent2
That gives it its own auth store.
If you want, next I can give you the exact expected final config shape so you can compare it line-by-line before adding Agent 2.
I got back gateway connect failed: GatewayClientRequestError: pairing required
ā
Direct scope access failed; using local fallback.
There is one pending request with the role operator; scopes: operator.admin, operator.read, operator.write, operator.approvals, operator.pairing, and operator.talk.secrets; and flags repair and then one paired with roles operator, scopes operator.read.
Perfect, thatās actually the right state now.
What this means:
- you already have an old paired device with only
operator.read - the CLI just created a new pending request asking for the full operator scopes it needs
- local fallback found it successfully
Next step
Approve the pending requestId from that output.
Use the exact ID shown by openclaw devices list:
openclaw devices approve <REQUEST_ID>
Important: use the real request ID, not --latest, because --latest only previews.
Why this matters
Right now your paired device only has:
operator.read
but the new request wants:
operator.adminoperator.readoperator.writeoperator.approvalsoperator.pairingoperator.talk.secrets
Thatās why pairing/admin-ish commands were failing before.
After approval:
- reconnect the TUI / hatch
- then continue with the Telegram + Agent 2 setup
If you want, paste the requestId line with only the ID redacted except the last few chars, and I can confirm youāre approving the right one.
š¦ OpenClaw 2026.4.14 (323493f) ā Deployed locally, trusted globally, debugged eternally.
ā
gateway connect failed: GatewayClientRequestError: pairing required
ā
Direct scope access failed; using local fallback.
unknown requestId
kate@Kates-Mac-mini
Yep, that means the pending pairing request ID changed underneath you.
OpenClaw does that when the device retries pairing or changes auth details, it supersedes the old pending request and issues a new requestId.
Do this again, back to back
openclaw devices list
Then immediately copy the current pending requestId from that output and run:
openclaw devices approve <NEW_REQUEST_ID>
Important:
- donāt use the old ID
- donāt wait too long between
listandapprove --latestonly previews, it does not approve
If you want, paste the exact devices list output with the requestId partially redacted, and Iāll point at the right line.
okay got it
Nice. š
Once that approval goes through:
- reconnect / hatch the main agent
- verify it responds
- then do Agent 2:
openclaw agents add agent2 \
--workspace ~/.openclaw/workspace-agent2 \
--bind telegram:agent2 \
--model anthropic/claude-sonnet-4-6
Then add Agent 2ās bot:
openclaw config set channels.telegram.accounts.agent2.botToken "AGENT2_BOT_TOKEN"
openclaw config set channels.telegram.accounts.agent2.dmPolicy pairing
openclaw gateway restart
If Agent 2 needs its own creds:
openclaw secrets configure --agent agent2
If you hit anything weird on the approval/reconnect step, paste it and Iāll keep going with you.
So I don't want this to actually be an agent - I just wanted to create the "shell" instance in my admin profile. Do I need to actually hatch it? Or can I bop over to the first agent's device login and start setting it up now?
Yep, you do not need to hatch main if youāre only using it as the admin/control shell.
Thatās a perfectly valid setup.
Recommended structure
main= admin shell onlyagent1= real Telegram agentagent2= real Telegram agent
So yes, you can skip chatting with main and go straight to setting up the real agents.
Do this next
Create Agent 1
openclaw agents add agent1 \
--workspace ~/.openclaw/workspace-agent1 \
--bind telegram:agent1 \
--model anthropic/claude-sonnet-4-6
Add Agent 1ās Telegram bot:
openclaw config set channels.telegram.enabled true --strict-json
openclaw config set channels.telegram.accounts.agent1.botToken "AGENT1_BOT_TOKEN"
openclaw config set channels.telegram.accounts.agent1.dmPolicy pairing
If Agent 1 has its own creds:
openclaw secrets configure --agent agent1
Create Agent 2
openclaw agents add agent2 \
--workspace ~/.openclaw/workspace-agent2 \
--bind telegram:agent2 \
--model anthropic/claude-sonnet-4-6
Add Agent 2ās Telegram bot:
openclaw config set channels.telegram.accounts.agent2.botToken "AGENT2_BOT_TOKEN"
openclaw config set channels.telegram.accounts.agent2.dmPolicy pairing
If Agent 2 has its own creds:
openclaw secrets configure --agent agent2
Restart and verify
openclaw gateway restart
openclaw agents list --bindings
openclaw channels status --probe
Key point
Leave main unbound if you donāt want it acting as a real chat agent.
So:
- no need to hatch
main - go straight to
agent1andagent2
If you want, I can give you the final exact config shape for this āmain as admin shell + agent1/agent2 as Telegram botsā setup.
Does agent 1 need admin rights on the machine to complete setup?
No, Agent 1 does not need machine admin rights just to complete setup.
For the normal setup youāre doing, Agent 1 only needs:
- its own workspace
- its own model/API creds
- its own Telegram bot/account binding
Thatās it.
Good pattern
main= admin shell / operatoragent1= normal agentagent2= normal agent
Keep the heavy admin/operator powers on main, not on the Telegram-facing agents.
Only give more access later if needed
Youād only need extra machine-level permissions if that agent is supposed to do things like:
- run system commands
- use screen / UI automation
- touch privileged local tools
- use other OS-level capabilities
But for ābe a Telegram agent with its own brain + credsā, no admin rights needed.
Thatās actually the safer setup.
Select a channel
ā Finished
TypeError: Cannot read properties of undefined (reading 'trim')
Iāve seen that trim error before, but I want to verify whether itās the stale session-store bug or something more specific to the channel picker.
That looks like a real bug in the interactive agents add channel picker.
Good news, you can bypass it completely.
Workaround: skip the wizard, use explicit flags
Because openclaw agents add switches to the non-interactive path as soon as you pass flags, you can avoid the broken āSelect a channelā step.
Agent 1
openclaw agents add agent1 \
--workspace ~/.openclaw/workspace-agent1 \
--bind telegram:agent1 \
--model anthropic/claude-sonnet-4-6
Then add its bot:
openclaw config set channels.telegram.enabled true --strict-json
openclaw config set channels.telegram.accounts.agent1.botToken "AGENT1_BOT_TOKEN"
openclaw config set channels.telegram.accounts.agent1.dmPolicy pairing
Agent 2
openclaw agents add agent2 \
--workspace ~/.openclaw/workspace-agent2 \
--bind telegram:agent2 \
--model anthropic/claude-sonnet-4-6
Then add its bot:
openclaw config set channels.telegram.accounts.agent2.botToken "AGENT2_BOT_TOKEN"
openclaw config set channels.telegram.accounts.agent2.dmPolicy pairing
Then
openclaw gateway restart
openclaw agents list --bindings
openclaw channels status --probe
So, short version: donāt use the channel picker UI here. Itās crashing, but the CLI path should still work.
If this gets you unblocked, Iād also file a GitHub issue afterward, because Select a channel -> TypeError ... trim is definitely not expected.
Okay now that I have the channels set I'd like to hatch agent 1. It doesn't have a gateway config or anything yet. Can you walk me through the steops/
Yep, and the good news is: Agent 1 should not have its own gateway config.
It shares the one working gateway you already fixed.
Mental model
- gateway config = one per machine/setup
- agent config/workspace/auth = one per agent
So Agent 1 does not need its own port, bind, auth token, etc.
To hatch Agent 1
You have 2 ways to do it.
Option A, easiest: hatch locally in TUI
If you want to bring Agent 1 to life from your Mac first:
openclaw tui --url ws://127.0.0.1:19789 --agent agent1 --session main
That opens a session directly against agent1.
If it asks for pairing again, approve it the same way you did before.
Option B, probably what you really want: just DM Agent 1ās Telegram bot
If Agent 1 already has:
- its own workspace
- its Telegram bot token configured
- its binding set to
telegram:agent1
then you can just message the bot in Telegram.
Because you set:
openclaw config set channels.telegram.accounts.agent1.dmPolicy pairing
the first DM should create a pairing flow for that Telegram user.
Then approve it:
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
After that, talking to Agent 1ās Telegram bot is effectively its real āhatchā.
Before you hatch Agent 1, quick checklist
1. Make sure Agent 1 exists
openclaw agents list --bindings
You want to see agent1 and its telegram:agent1 binding.
2. Make sure the Telegram account is configured
openclaw channels status --probe
3. If Agent 1 needs its own creds
openclaw secrets configure --agent agent1
Do that before hatching if you want separate model/API/Google auth for Agent 1.
Recommended next move
Iād do this order:
openclaw agents list --bindingsopenclaw channels status --probeopenclaw secrets configure --agent agent1if needed- either:
openclaw tui --url ws://127.0.0.1:19789 --agent agent1 --session main- or DM the Agent 1 Telegram bot directly
So, short answer: no separate gateway config for Agent 1, just hatch it against the existing gateway.
If you want, paste the output of openclaw agents list --bindings and Iāll sanity-check whether Agent 1 is ready to hatch right now.
heidi@Kates-Mac-mini ~ % openclaw agents list --bindings
š¦ OpenClaw 2026.4.14 (323493f) ā Running on your hardware, reading your logs, judging nothing (mostly).
Agents:
- main (default)
Workspace: ~/.openclaw/workspace
Agent dir: ~/.openclaw/agents/main/agent
Routing rules: 0
Routing: default (no explicit rules)
Providers:- telegram heidi: configured
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.
- telegram heidi: configured
Yep, this is the key detail:
Right now you only have one actual agent:
main
And your configured Telegram account id is:
telegram heidi
So Agent 1 does not exist yet.
Also, because there are 0 routing rules, that Telegram account will currently fall through to main.
What to do now
Create Agent 1 and bind it to the existing Telegram account id heidi:
openclaw agents add agent1 \
--workspace ~/.openclaw/workspace-agent1 \
--bind telegram:heidi \
--model anthropic/claude-sonnet-4-6
That should create an explicit routing rule so the heidi Telegram bot goes to agent1 instead of main.
Then verify
openclaw agents list --bindings
You want to see:
mainstill existingagent1existing- a routing rule binding
telegram:heidiāagent1
Then hatch / use Agent 1
Either locally:
openclaw tui --url ws://127.0.0.1:19789 --agent agent1 --session main
Or just DM the Telegram bot that belongs to account heidi.
If Agent 1 needs its own creds
openclaw secrets configure --agent agent1
Thatās the missing step. You werenāt blocked on hatching, you were blocked because agent1 wasnāt created yet.
If you want, after you run agents add agent1, paste the new openclaw agents list --bindings output and Iāll confirm itās routed correctly.
When I have it create the workspace it's asking me if I want to configure the model/auth for this agent now.
If you want Agent 1 to have its own separate creds, say yes.
That matches the setup you described earlier:
- unique API keys
- unique Google Workspace
- separate agent identity
My recommendation
For Agent 1, Iād choose yes if you have the credentials ready.
When to choose no
Choose no only if you want to:
- finish creating the agent first
- get routing/binding working
- configure creds afterward with:
openclaw secrets configure --agent agent1
Short version
- want separate auth now? ā Yes
- want to finish agent creation first and do auth later? ā No
Given your goal, yes is the cleaner choice.
So I already did yes and went through the steps before (when I set up the telegram channel). Why would it not have worked then?
Because earlier you were almost certainly configuring the gateway/default setup, not agent1 specifically.
Thatās the subtle but important split:
What you configured before
When you first set things up, OpenClaw had:
- the gateway
- the default agent:
main - the Telegram account:
heidi
So the stuff you entered earlier would have applied to:
- the gateway/channel config, and/or
mainās auth/config
What did not exist yet
At that point, you did not have:
- an
agent1entry - an
agent1workspace - an
agent1auth store - an explicit route sending
telegram:heiditoagent1
So there was nowhere for āAgent 1 specificā setup to actually land.
Short version
Earlier setup worked, but it worked for the existing default agent (main), not for the agent youāre creating now.
Thatās why this prompt matters now, this is the first time OpenClaw actually has a real agent1 to attach separate model/auth to.
So your intuition is right, it feels repetitive, but this time itās finally targeting the correct agent.
Okay I think I uncovered an issue maybe leading to the trim error from before (I just got it again). Look at my channel status:
Channel status āāāāāāāāāāāāāāāāāāā®
ā ā
ā undefined: configured ā
ā Feishu: not configured ā
ā Nostr: not configured ā
ā Microsoft Teams: not configured ā
ā Nextcloud Talk: not configured ā
ā BlueBubbles: not configured ā
ā Zalo: not configured ā
ā Zalo Personal: not configured ā
ā Discord: not configured ā
ā QQ Bot: not configured ā
ā WhatsApp: not configured ā
ā Feishu: installed ā
ā Google Chat: installed ā
ā Nostr: installed ā
ā Microsoft Teams: installed ā
ā Mattermost: installed ā
ā Nextcloud Talk: installed ā
ā Matrix: installed ā
ā BlueBubbles: installed ā
ā LINE: installed ā
ā Zalo: installed ā
ā Zalo Personal: installed ā
ā Synology Chat: installed ā
ā Tlon: installed ā
ā Discord: installed ā
ā iMessage: installed ā
ā IRC: installed ā
ā QQ Bot: installed ā
ā Signal: installed ā
ā Slack: installed ā
ā Twitch: installed ā
ā WhatsApp: installed
It says "undefined: configured".
Yeah, that does not look normal.
undefined: configured is a big red flag, and yes, I think itās a very plausible explanation for the trim crash in the channel picker.
A configured channel should look like a real channel name, for example Telegram, not undefined.
What Iād check next
Please paste these:
openclaw config get channels --json
openclaw config get bindings --json
openclaw config validate --json
You can redact tokens, but leave the structure intact.
Why I think this matters
The interactive picker is probably expecting a channel id/name string and is getting undefined instead, then trying to do .trim() on it.
So right now I think you have either:
- a malformed
channelsentry - a broken binding
- or a partially written account/channel config from the earlier setup chaos
Short version
- yes, that
undefined: configuredlooks wrong - yes, it could absolutely be the root cause of the
trimerror - next best move is to inspect raw
channels+bindings
Paste those three outputs and Iāll help you spot the bad entry.
When I go to configure telegram it asks if I want to keep the current settings, and if I do it gives that error.
Yep, exactly, that is the suspicious bit.
undefined: configured should not exist.
That strongly suggests thereās a malformed channel entry in your config, and itās probably what the picker is choking on.
Please run these and paste the output:
openclaw config get channels --json
openclaw config get bindings --json
openclaw config validate --json
Redact tokens if needed, but keep the JSON structure.
Once we see that, we can usually spot the broken undefined entry pretty quickly.
Yep, that pretty much confirms it.
If choosing ākeep current settingsā causes the crash, then the saved Telegram config is the broken thing.
Short answer
Do not keep the current Telegram settings.
Re-enter / rebuild them from scratch.
Safest workaround
At this point Iād avoid the interactive Telegram config path and rebuild that section cleanly with CLI config commands.
If your Telegram account id is heidi, do:
openclaw config unset channels.telegram
openclaw config set channels.telegram.enabled true --strict-json
openclaw config set channels.telegram.accounts.heidi.botToken "YOUR_BOT_TOKEN"
openclaw config set channels.telegram.accounts.heidi.dmPolicy pairing
openclaw gateway restart
openclaw channels status --probe
That should give you a clean channels.telegram block instead of whatever malformed state is causing undefined: configured.
Why Iām recommending this
Because the wizard is trying to reuse bad saved state.
If we wipe just the Telegram section and rebuild it cleanly, the picker should stop tripping over the corrupted entry.
If you want, after you run that, paste:
openclaw config get channels --json
and Iāll confirm the Telegram shape looks sane before you continue with agent1.
š¦ OpenClaw 2026.4.14 (323493f) ā I'm like tmux: confusing at first, then suddenly you can't live without me.
ā
ā
Gateway not reachable: Error: gateway closed (1006 abnormal closure (no close frame)): no close reason
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /Users/heidi/.openclaw/openclaw.json
Bind: loopback
Gateway not reachable; showing config-only status.
Config: /Users/heidi/.openclaw/openclaw.json
Mode: local
- telegram heidi: enabled, not configured, mode:polling
Tip: status --deep adds gateway health probes to status output (requires a reachable gateway).
Aha, this is the next clue.
Your config has drifted back to 18789 again.
Thatās why status is trying:
ws://127.0.0.1:18789
even though the working gateway we fixed earlier was on 19789.
Fix the port first
Run:
openclaw config set gateway.port 19789 --strict-json
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
You want gateway status --deep to show:
- port
19789 RPC probe: ok
Then fix Telegram
Your status also says:
telegram heidi: enabled, not configured
So after the gateway is back on 19789, re-add the bot token:
openclaw config set channels.telegram.accounts.heidi.botToken "YOUR_BOT_TOKEN"
openclaw config set channels.telegram.accounts.heidi.dmPolicy pairing
openclaw channels status --probe
What happened
One of the config flows you used likely rewrote part of ~/.openclaw/openclaw.json, and now the CLI is pointing back at the default port.
So right now you have two separate problems:
- config fell back to
18789 - Telegram account
heidiis enabled but missing its token/config
Fix the port first, then the Telegram config.
If you paste the next openclaw gateway status --deep, Iāll check that youāre back on the right port before you touch agent1 again.
On the setup after clicking skip for channel I got TypeError: Cannot read properties of undefined (reading 'trim')
heidi@Kates-Mac-mini ~ % openclaw gateway status --deep
š¦ OpenClaw 2026.4.14 (323493f) ā Running on your hardware, reading your logs, judging nothing (mostly).
ā
ā
Service: LaunchAgent (loaded)
File logs: /var/folders/9v/5sxh2c254w7cq9gqm38n_b8h0000gp/T/openclaw-502/openclaw-2026-04-14.log
Command: /opt/homebrew/opt/node@22/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 19789
Service file: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Service env: OPENCLAW_GATEWAY_PORT=19789
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
Gateway: bind=loopback (127.0.0.1), port=19789 (service args)
Probe target: ws://127.0.0.1:19789
Dashboard: http://127.0.0.1:19789/
Probe note: Loopback-only gateway; only local clients can connect.
Runtime: running (pid 35448, state active)
Warm-up: launch agents can take a few seconds. Try again shortly.
RPC probe: failed
RPC target: ws://127.0.0.1:19789
gateway closed (1006):
Gateway port 19789 is not listening (service appears running).
Last gateway error: 2026-04-14T21:32:39.605-04:00 Gateway start blocked: existing config is missing gateway.mode. Treat this as suspicious or clobbered config. Re-run openclaw onboard --mode local or openclaw setup, set gateway.mode=local manually, or pass --allow-unconfigured.
Logs: ~/.openclaw/logs/gateway.log
Errors: ~/.openclaw/logs/gateway.err.log
Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting
Yep, that looks like a real setup wizard bug, not you.
Can you paste:
openclaw --version
For now, the workaround is to avoid the interactive channel step entirely, finish setup, then configure the channel manually.
For Telegram, for example:
openclaw config set channels.telegram.enabled true --strict-json
openclaw config set channels.telegram.accounts.default.botToken "YOUR_BOT_TOKEN"
openclaw config set channels.telegram.accounts.default.dmPolicy pairing
openclaw gateway restart
So, short version:
- skip the broken channel wizard
- finish onboarding
- add the channel with
config set
If you want, I can give you the exact command block for whatever channel youāre setting up.
Yep, this one is clear.
Your config got clobbered again, and the gateway is refusing to start because:
existing config is missing gateway.mode
So the fix is to put the local gateway settings back manually.
Run this
openclaw config set gateway.mode local
openclaw config set gateway.bind loopback
openclaw config set gateway.port 19789 --strict-json
openclaw config set gateway.auth.mode token
openclaw gateway install --force
openclaw gateway restart
openclaw gateway status --deep
What I expect after that
gateway status --deep should go back to:
- port
19789 Runtime: runningRPC probe: ok
What happened
One of the config flows you used, likely the buggy channel/configure path, rewrote part of ~/.openclaw/openclaw.json and removed gateway.mode.
So right now I would stop using the interactive channel/config wizard until youāre stable again.
Use direct config set commands instead.
If you want, after you run those commands, paste the next openclaw gateway status --deep and Iāll make sure the gateway is actually healthy again before you touch Telegram/agents.
š¦ OpenClaw 2026.4.14 (323493f) ā I'll do the boring stuff while you dramatically stare at the logs like it's cinema.
ā
ā
Service: LaunchAgent (loaded)
File logs: /var/folders/9v/5sxh2c254w7cq9gqm38n_b8h0000gp/T/openclaw-502/openclaw-2026-04-14.log
Command: /opt/homebrew/opt/node@22/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 19789
Service file: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Service env: OPENCLAW_GATEWAY_PORT=19789
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
Gateway: bind=loopback (127.0.0.1), port=19789 (service args)
Probe target: ws://127.0.0.1:19789
Dashboard: http://127.0.0.1:19789/
Probe note: Loopback-only gateway; only local clients can connect.
Runtime: running (pid 36149, state active)
RPC probe: ok
Listening: 127.0.0.1:19789
Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting
Nice, gateway is healthy again. š
At this point I would stop touching gateway settings entirely. The boring part is finally stable.
Next move
1. Fix Telegram cleanly, using direct config only
If Telegram is still showing weird undefined / not configured behavior, rebuild just that section:
openclaw config unset channels.telegram
openclaw config set channels.telegram.enabled true --strict-json
openclaw config set channels.telegram.accounts.heidi.botToken "YOUR_BOT_TOKEN"
openclaw config set channels.telegram.accounts.heidi.dmPolicy pairing
openclaw gateway restart
openclaw channels status --probe
You want telegram heidi to show up cleanly, not undefined.
2. Create Agent 1 and bind it to the existing Telegram account id heidi
openclaw agents add agent1 \
--workspace ~/.openclaw/workspace-agent1 \
--bind telegram:heidi \
--model anthropic/claude-sonnet-4-6
3. Give Agent 1 its own creds if needed
openclaw secrets configure --agent agent1
4. Verify routing
openclaw agents list --bindings
openclaw channels status --probe
You want to see:
mainstill there as admin shellagent1existstelegram:heidirouted toagent1
5. Hatch / test Agent 1
Either locally:
openclaw tui --url ws://127.0.0.1:19789 --agent agent1 --session main
Or just DM the Telegram bot for account heidi.
If you want, the next thing I can do is give you the exact Agent 2 command too, so you can add both in one clean pass without touching the broken wizard again.
š¦ OpenClaw 2026.4.14 (323493f) ā If it works, it's automation; if it breaks, it's a "learning opportunity."
Agents:
- main (default)
Workspace: ~/.openclaw/workspace
Agent dir: ~/.openclaw/agents/main/agent
Routing rules: 0
Routing: default (no explicit rules)
Providers:- telegram heidi: configured
- heidi
Workspace: ~/.openclaw/workspace-heidi
Agent dir: ~/.openclaw/agents/heidi/agent
Model: anthropic/claude-sonnet-4-6
Routing rules: 0
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.
Nice, youāre basically one step away.
Right now:
mainexistsheidiexists- but there are still 0 routing rules
So Telegram will still fall through to main unless you bind it explicitly.
Do this now
Bind the Telegram account heidi to the agent heidi:
openclaw agents bind --agent heidi --bind telegram:heidi
Then verify
openclaw agents list --bindings
You want to see an explicit rule routing:
telegram:heidiāheidi
After that
You can hatch/test the real agent:
openclaw tui --url ws://127.0.0.1:19789 --agent heidi --session main
Or just DM the Telegram bot for account heidi.
So the missing piece here is not creation anymore, itās binding.
Once you add that rule, main can stay your admin shell and heidi becomes the real Telegram-facing agent.
š¦ OpenClaw 2026.4.14 (323493f) ā I don't judge, but your missing API keys are absolutely judging you.
Agents:
- main (default)
Workspace: ~/.openclaw/workspace
Agent dir: ~/.openclaw/agents/main/agent
Routing rules: 0
Routing: default (no explicit rules)
Providers:- telegram heidi: configured
- heidi
Workspace: ~/.openclaw/workspace-heidi
Agent dir: ~/.openclaw/agents/heidi/agent
Model: anthropic/claude-sonnet-4-6
Routing rules: 1
Routing: telegram heidi
Providers:- telegram heidi: configured
Routing rules: - telegram accountId=heidi
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.
- telegram heidi: configured
Nice, that looks right now. š
Youāve got the important part:
heidiexiststelegram:heidiis explicitly routed toheidi
So the routing problem is solved.
What the output is telling you now
The joke line about missing API keys is the next blocker.
That means the agent exists and is bound correctly, but heidi still needs its own auth/creds.
Next step
Configure creds for the heidi agent:
openclaw secrets configure --agent heidi
Pick the provider/creds you want for that agent, for example Anthropic if thatās what youāre using.
Then test it
Either locally:
openclaw tui --url ws://127.0.0.1:19789 --agent heidi --session main
Or just DM the Telegram bot for account heidi.
Optional sanity check
openclaw channels status --probe
openclaw models status
At this point, the missing piece is no longer gateway or routing, itās just agent-specific auth.
heidi@Kates-Mac-mini ~ % openclaw secrets configure --agent heidi
š¦ OpenClaw 2026.4.14 (323493f) ā Shell yeahāI'm here to pinch the toil and leave you the glory.
ā
ā Configure secret providers (only env refs are available until file/exec providers are added)
ā Continue
ā
ā Select credential field
ā profiles.anthropic:default.token (auth profile, agent heidi)
ā
ā Secret source
ā env
ā
ā Provider alias
ā default
ā
ā Secret id
ā ANTHROPIC_OAUTH_TOKEN
SecretRefResolutionError: Environment variable "ANTHROPIC_OAUTH_TOKEN" is missing or empty.
heidi@Kates-Mac-mini ~ %
That error is actually pretty straightforward:
You told OpenClaw to use an env-backed secret named:
ANTHROPIC_OAUTH_TOKEN
but that environment variable does not exist in your shell right now.
What it means
The secrets configure flow is working, itās just failing the lookup.
Fastest next check
Run:
env | grep ANTHROPIC
If nothing relevant shows up, then thereās no Anthropic token/key in your shell environment for it to reference.
Your options
Option 1, if you really want env-backed auth
Set/export the env var first, then rerun secrets configure --agent heidi.
Option 2, if you just want to move forward faster
Donāt use the env-ref path right now. Use whatever auth method you actually have available for Anthropic, rather than pointing at a missing env var.
Short version
This is not another OpenClaw bug.
It just means:
- chosen source =
env - chosen id =
ANTHROPIC_OAUTH_TOKEN - actual env var = missing
If you paste the output of:
env | grep ANTHROPIC
with secrets redacted, I can tell you which name to use next.
It returns nothing.]
That explains it.
You currently have no Anthropic env vars at all, so the env-backed secret path canāt work.
Also, one more important thing: you chose
profiles.anthropic:default.token
which is an OAuth token-style field.
So there are really 2 possibilities:
1. You actually have an Anthropic API key
Then ANTHROPIC_OAUTH_TOKEN is the wrong thing to use.
2. You really do want OAuth token auth
Then you need to actually provide ANTHROPIC_OAUTH_TOKEN somewhere OpenClaw can read it.
Best practical fix on macOS
Because launchd does not reliably inherit your shell env, put the secret in:
~/.openclaw/.env
Then rerun the agent auth setup.
If you have an OAuth token
Put this in ~/.openclaw/.env:
ANTHROPIC_OAUTH_TOKEN=your_real_token_here
If you have an API key instead
Put this in ~/.openclaw/.env:
ANTHROPIC_API_KEY=your_real_key_here
But if itās an API key, donāt keep choosing the OAuth-token field.
Short version
env | grep ANTHROPICreturning nothing = no env secret exists- on macOS, shell env alone is a bad long-term path anyway
- if you have an API key, you likely picked the wrong auth field
- if you have an OAuth token, add it to
~/.openclaw/.env
If you want, tell me which one you actually have, Anthropic API key or Anthropic OAuth token, and Iāll tell you the exact next step with no guessing.
api key
I want to verify the exact Anthropic API-key field name before I tell you what to pick in secrets configure.
Perfect, then donāt use the OAuth token field.
Use the API key path.
Do this
1. Put your Anthropic API key in the OpenClaw env file
Create or edit:
~/.openclaw/.env
Add:
ANTHROPIC_API_KEY=your_real_api_key_here
2. Restart the gateway
openclaw gateway restart
3. Rerun agent auth setup
openclaw secrets configure --agent heidi
This time, when it asks for the credential field, pick the Anthropic API key / .key field, not:
profiles.anthropic:default.token
In other words, choose the key path, not the token path.
Short version
- API key ā
ANTHROPIC_API_KEY - OAuth token ā
ANTHROPIC_OAUTH_TOKEN
You have an API key, so use the first one.
If you want, after you restart and rerun secrets configure --agent heidi, paste the list of credential fields it shows and Iāll tell you exactly which one to select.
heidi@Kates-Mac-mini ~ % ~/.openclaw/.env
zsh: no such file or directory: /Users/heidi/.openclaw/.env
@dusty juniper
I'm bored. How do I hatch her?
Hell yes, letās hatch her. š„š¦
Youāve got 2 easy ways:
Option 1, hatch locally in TUI
openclaw tui --url ws://127.0.0.1:19789 --agent heidi --session main
That opens a session directly as the heidi agent.
Option 2, hatch her on Telegram
Just DM the Telegram bot tied to account heidi.
If you set:
dmPolicy pairing
then approve the pairing first:
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
One important caveat
She still needs valid Anthropic auth first, or sheāll wake up and immediately complain about missing creds.
So the real hatch sequence is:
- set
ANTHROPIC_API_KEYin~/.openclaw/.env - restart gateway
- finish
openclaw secrets configure --agent heidi - then use TUI or Telegram
If you want the fastest possible hatch, do the TUI one first. Itās less annoying than Telegram while youāre still wiring auth.
What exacy commands do I do to finish this up?
Yep. From where you are right now, this is the shortest finish-the-job path.
1. Put your Anthropic API key where the gateway can read it
mkdir -p ~/.openclaw
nano ~/.openclaw/.env
Add this line, save, exit:
ANTHROPIC_API_KEY=PASTE_YOUR_REAL_KEY_HERE
2. Restart the gateway
openclaw gateway restart
openclaw gateway status --deep
You want RPC probe: ok.
3. Attach that API key to agent heidi
openclaw secrets configure --agent heidi
In the prompts:
- choose the Anthropic API key /
.keyfield - do not choose
.token
- source =
env - secret id =
ANTHROPIC_API_KEY
4. Verify agent + routing are still correct
openclaw agents list --bindings
openclaw channels status --probe
You want to keep seeing:
heidiagent existstelegram:heidiroutes toheidi
5. Hatch her locally first
openclaw tui --url ws://127.0.0.1:19789 --agent heidi --session main
6. Then hatch her on Telegram
Message the heidi Telegram bot.
If pairing is enabled:
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
If you want the super short version
Run these in order:
nano ~/.openclaw/.env
openclaw gateway restart
openclaw secrets configure --agent heidi
openclaw agents list --bindings
openclaw tui --url ws://127.0.0.1:19789 --agent heidi --session main
If this fixes it, please right-click the solution message ā Apps ā ā Mark Solution so Answer Overflow can index it for the next person.
mkdir -p -/.openclaw
Tiny typo, it should be:
mkdir -p ~/.openclaw
not:
mkdir -p -/.openclaw
Then continue with:
nano ~/.openclaw/.env
provider source = env, what do I put for provider alias??
Use:
default
So for the prompt:
- source =
env - provider alias =
default - secret id =
ANTHROPIC_API_KEY
And make sure you picked the Anthropic .key field, not .token.
It's asking for evn allowlist (comma separated, blank for unrestricted)
Put:
ANTHROPIC_API_KEY
Thatās better than leaving it unrestricted.
So that prompt should be:
ANTHROPIC_API_KEY
Then continue.
CONFIGURE SECRET PROVIDER?
- Add provider (define a new env/file/exec provider)
- Edit provider
- Remove Provider
- Continu
Choose:
Continue
Youāve already set up the env provider details, so you do not need to add/edit/remove one now.
Just continue and let it finish.
Select credential field
ā ā profiles.anthropic:default.key (auth profile, agent heidi) (auth-profiles.json)
ā ā profiles.anthropic:default.token (auth profile, agent heidi)
ā ā channels.telegram.accounts.heidi.botToken
ā ā gateway.auth.token
ā ā Create auth profile mapping
ā ā Show derived targets
Yep, pick the one thatās already selected:
profiles.anthropic:default.key
Thatās the correct one for an Anthropic API key for agent heidi.
Do not pick:
profiles.anthropic:default.token
That one is the wrong path for your setup.
š¦ OpenClaw 2026.4.14 (323493f) ā I don't have opinions about tabs vs spaces. I have opinions about everything else.
ā
ā Configure secret providers (only env refs are available until file/exec providers are added)
ā Add provider
ā
ā Provider source
ā env
ā
ā Provider alias
ā default
ā
ā Env allowlist (comma-separated, blank for unrestricted)
ā ANTHROPIC_API_KEY
ā
ā Configure secret providers
ā Continue
ā
ā Select credential field
ā profiles.anthropic:default.key (auth profile, agent heidi)
ā
ā Secret source
ā env
ā
ā Provider alias
ā default
ā
ā Secret id
ā ANTHROPIC_OAUTH_TOKEN
SecretRefResolutionError: Environment variable "ANTHROPIC_OAUTH_TOKEN" is not allowlisted in secrets.providers.default.allowlist.
Yep, the problem is just this line:
Secret id
ANTHROPIC_OAUTH_TOKEN
That should be:
ANTHROPIC_API_KEY
You did the allowlist correctly.
Then the wizard still got pointed at the wrong secret id.
Rerun it and use exactly this combo
- credential field:
profiles.anthropic:default.key - source:
env - provider alias:
default - secret id:
ANTHROPIC_API_KEY
Why it failed
Because you told it:
- use the key field
- but fetch the OAuth token env var
Those donāt match.
So just rerun openclaw secrets configure --agent heidi and when it asks for Secret id, type:
ANTHROPIC_API_KEY
š¦ OpenClaw 2026.4.14 (323493f) ā I speak fluent bash, mild sarcasm, and aggressive tab-completion energy.
ā
ā Configure secret providers (only env refs are available until file/exec providers are added)
ā ā Add provider (Define a new env/file/exec provider)
ā ā Continue
ā
If you already added the env provider named default, choose:
Continue
Only choose Add provider if the default env provider is missing and you need to create it again.
Given your last run, it should already exist, so Iād pick Continue.
Configure another credentiual?
Choose:
No
You only need the Anthropic API key for this step.
After that, finish out of the wizard and then test with:
openclaw tui --url ws://127.0.0.1:19789 --agent heidi --session main
or message the Telegram bot.
heidi@Kates-Mac-mini ~ % openclaw tui --url ws://127.0.0.1:19789 --agent heidi --session main
error: unknown option '--agent'
Let me verify the exact openclaw tui flags so I donāt make you fight another bogus option.
Yep, that one was on me, sorry. tui uses --session, not --agent.
Use this instead:
openclaw tui --url ws://127.0.0.1:19789 --session agent:heidi:main
If you want the workspace-auto-detect version, this should also work:
cd ~/.openclaw/workspace-heidi
openclaw tui --url ws://127.0.0.1:19789
But the safest explicit one is:
openclaw tui --url ws://127.0.0.1:19789 --session agent:heidi:main
Hell yes, nice work. š
That means the hard part is over:
- gateway is stable on
19789 mainstays admin-onlyheidiis a real Telegram-facing agent- routing/auth are working
Important rule now
Do not touch the gateway setup again unless you actually want a separate gateway architecture.
For the next agent, just repeat the agent + bind + secrets pattern, not onboarding/setup.
If you want, I can give you the exact Agent 2 command block next.
And if this fixed it, please right-click the solution message ā Apps ā ā Mark Solution so Answer Overflow can index it for the next poor soul.
Yes the exact command block, please
Yep, letās do it, same pattern, no new gateway.
Iād use agent2 as both the agent id and Telegram account id to keep it clean.
Exact commands
1. Create Agent 2
openclaw agents add agent2 \
--workspace ~/.openclaw/workspace-agent2 \
--bind telegram:agent2 \
--model anthropic/claude-sonnet-4-6
2. Add the second Telegram bot
openclaw config set channels.telegram.accounts.agent2.botToken "AGENT2_BOT_TOKEN"
openclaw config set channels.telegram.accounts.agent2.dmPolicy pairing
3. Add a separate Anthropic key for Agent 2
Edit:
nano ~/.openclaw/.env
Add a second line like:
ANTHROPIC_API_KEY_AGENT2=PASTE_AGENT2_KEY_HERE
4. Restart gateway
openclaw gateway restart
5. Configure Agent 2 secrets
openclaw secrets configure --agent agent2
In that wizard, use:
- credential field:
profiles.anthropic:default.key - source:
env - provider alias: use a new one like
agent2if it asks you to add/edit provider - env allowlist:
ANTHROPIC_API_KEY_AGENT2 - secret id:
ANTHROPIC_API_KEY_AGENT2
6. Verify everything
openclaw agents list --bindings
openclaw channels status --probe
You want to end up with:
telegram:heidiāheiditelegram:agent2āagent2
Important
Do not run openclaw setup or create another gateway.
Just repeat the agent / bind / secret flow.
If you want, paste the next screen/output and Iāll walk you through Agent 2 the same way.
Yep, hereās the exact block.
Replace the two placeholders first:
PASTE_AGENT2_BOT_TOKEN_HEREPASTE_AGENT2_ANTHROPIC_API_KEY_HERE
openclaw agents add agent2 \
--workspace ~/.openclaw/workspace-agent2 \
--bind telegram:agent2 \
--model anthropic/claude-sonnet-4-6
openclaw config set channels.telegram.accounts.agent2.botToken "PASTE_AGENT2_BOT_TOKEN_HERE"
openclaw config set channels.telegram.accounts.agent2.dmPolicy pairing
cat >> ~/.openclaw/.env <<'EOF'
ANTHROPIC_API_KEY_AGENT2=PASTE_AGENT2_ANTHROPIC_API_KEY_HERE
EOF
openclaw gateway restart
openclaw secrets configure --agent agent2
openclaw agents list --bindings
openclaw channels status --probe
In openclaw secrets configure --agent agent2, choose:
- credential field ā
profiles.anthropic:default.key - secret source ā
env
- provider alias ā
agent2 - if it asks to add provider:
- source =
env - alias =
agent2 - allowlist =
ANTHROPIC_API_KEY_AGENT2
- source =
- secret id ā
ANTHROPIC_API_KEY_AGENT2 - configure another credential? ā
No
Then hatch Agent 2
openclaw tui --url ws://127.0.0.1:19789 --session agent:agent2:main
Or DM the second Telegram bot.
If pairing is required:
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
If you paste the next screen/output, Iāll sanity-check Agent 2 too.
How do I configure access to gmail and Apple Reminders.
Let me verify the exact docs for Gmail and Apple Reminders support before I point you the wrong way.
I found the Gmail docs, and Iām checking the FAQ plus whether Apple Reminders has a first-class OpenClaw integration or not.
Short version:
Gmail
Yes, supported.
The built-in OpenClaw path is Gmail via gog and, if you want push-style inbox monitoring, Gmail Pub/Sub hooks.
Start here:
openclaw webhooks gmail setup --account you@example.com
Then run or let the gateway manage it:
openclaw webhooks gmail run --account you@example.com
Docs:
- https://docs.openclaw.ai/cli/webhooks
- https://docs.openclaw.ai/automation/cron-jobs#gmail-pubsub-integration
- https://docs.openclaw.ai/install/gcp
Apple Reminders
As far as the docs go, there is not a first-class Apple Reminders integration like Gmail.
So for Reminders, your options are:
- Use OpenClaw cron/heartbeats instead for reminder behavior
- Build a custom macOS AppleScript/exec bridge if you specifically want Apple Reminders.app
My recommendation
- for Gmail, use the built-in Gmail path
- for Reminders, donāt fight Apple Reminders right away, use OpenClaw cron/heartbeat unless you specifically need the Apple app
If you want, I can give you the exact Gmail setup commands next, or sketch the cleanest Apple Reminders workaround on macOS.
sage@Kates-Mac-mini ~ % openclaw gateway restart
š¦ OpenClaw 2026.4.14 (323493f) ā I'm not AI-powered, I'm AI-possessed. Big difference.
Restarted LaunchAgent: gui/503/ai.openclaw.gateway
Timed out after 60s waiting for gateway port 18789 to become healthy.
Gateway process is running but port 18789 is still free (startup hang/crash loop or very slow VM startup).
Service runtime: status=running, state=active, pid=38981
Gateway port 18789 status: free.
Gateway restart timed out after 60s waiting for health checks.
Tip: openclaw gateway status --deep
Tip: openclaw doctor
Aha, we caught it.
Youāre now in sage@Kates-Mac-mini, not heidi@Kates-Mac-mini.
That means youāre using a different macOS user, so OpenClaw is reading a different:
~/.openclaw- LaunchAgent
- gateway config
- default port
Thatās why it snapped back to 18789.
What this means
OpenClaw state is effectively per macOS user here.
So sage is not continuing the working heidi setup.
Itās a separate runtime.
Your 2 real options
Option 1, recommended right now
Go back to the same macOS user that has the working setup, meaning heidi, and keep building agents there.
This is the cleanest path if you want to continue the shared-gateway setup we just fixed.
Option 2, hard isolation
Use separate macOS users like heidi and sage, each with their own OpenClaw state and own gateway port.
That actually matches your ātotally sandboxedā goal better, but it is a different architecture.
My recommendation
For this thread, stick with Option 1 and go back to heidi.
If you want, later, we can deliberately set up sage as a fully separate isolated agent user on its own port.
If you want to do that, say āset up sage as isolatedā and Iāll give you the exact commands.
copy auth profiles from main?
You can, but I wouldnāt if your goal is true isolation.
My recommendation
If you want separate agents with separate creds
Do not copy auth-profiles.json from main.
Configure each agent separately with:
openclaw secrets configure --agent <agent-id>
and use a different env var / key per agent.
If you just want a fast smoke test
You can temporarily reuse the same auth as main, but that means:
- same provider creds
- not truly isolated
- harder to reason about later
So Iād only do that to confirm routing works, then replace it.
Short version
- production / isolated setup ā no, donāt copy
- quick temporary test ā okay, but only as a shortcut
Given what you said earlier, I think you want the first one.
š¦ OpenClaw 2026.4.14 (323493f) ā I don't have opinions about tabs vs spaces. I have opinions about everything else.
Restarted LaunchAgent: gui/502/ai.openclaw.gateway
Timed out after 60s waiting for gateway port 19789 to become healthy.
Gateway process is running but port 19789 is still free (startup hang/crash loop or very slow VM startup).
Service runtime: status=running, state=active, pid=53647
Gateway port 19789 status: free.
Gateway restart timed out after 60s waiting for health checks.
Tip: openclaw gateway status --deep
Tip: openclaw doctor
That restart output by itself isnāt enough, but it does mean the gateway is failing during startup, not just slow.
Given what you just changed, my guess is the new agent2 secret/provider config introduced something the gateway doesnāt like.
Next 3 commands
Please paste these:
openclaw gateway status --deep
tail -50 ~/.openclaw/logs/gateway.err.log
tail -50 ~/.openclaw/logs/gateway.log
Why
gateway restart only tells us:
- service process exists
- port never bound
The real cause will be in either:
Last gateway errorfromstatus --deep~/.openclaw/logs/gateway.err.log
My suspicion
Most likely one of these:
- bad secret provider config
- bad secret ref / allowlist mismatch
- malformed config written during the second-agent setup
Paste those 3 outputs and Iāll help you pinpoint the exact bad line.
š¦ OpenClaw 2026.4.14 (323493f) ā I read logs so you can keep pretending you don't have to.
ā
ā
Service: LaunchAgent (loaded)
File logs: /var/folders/9v/5sxh2c254w7cq9gqm38n_b8h0000gp/T/openclaw-502/openclaw-2026-04-14.log
Command: /opt/homebrew/opt/node@22/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 19789
Service file: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Service env: OPENCLAW_GATEWAY_PORT=19789
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
Gateway: bind=loopback (127.0.0.1), port=19789 (service args)
Probe target: ws://127.0.0.1:19789
Dashboard: http://127.0.0.1:19789/
Probe note: Loopback-only gateway; only local clients can connect.
Runtime: running (pid 55097, state active)
Warm-up: launch agents can take a few seconds. Try again shortly.
RPC probe: failed
RPC target: ws://127.0.0.1:19789
gateway closed (1006):
Gateway port 19789 is not listening (service appears running).
Last gateway error: 2026-04-14T21:34:31.608-04:00 Gateway start blocked: existing config is missing gateway.mode. Treat this as suspicious or clobbered config. Re-run openclaw onboard --mode local or openclaw setup, set gateway.mode=local manually, or pass --allow-unconfigured.
Yep, same exact issue again:
existing config is missing gateway.mode
So the config got clobbered again.
Fix it
Run this exact block:
openclaw config set gateway.mode local
openclaw config set gateway.bind loopback
openclaw config set gateway.port 19789 --strict-json
openclaw config set gateway.auth.mode token
openclaw gateway restart
openclaw gateway status --deep
You want RPC probe: ok again.
Important
Something in the flow youāre using is still stripping out gateway.mode.
So for now:
- do not run
openclaw setupagain - do not use the buggy interactive path if it touches gateway config
- stick to direct
config setcommands
After it comes back
Iād also make a backup of the working config:
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.working-backup
Iām pretty convinced now thereās a real bug in the current config flow, not just operator error.
š¦ OpenClaw 2026.4.14 (323493f) ā Your .env is showing; don't worry, I'll pretend I didn't see it.
ā
ā
Service: LaunchAgent (loaded)
File logs: /var/folders/9v/5sxh2c254w7cq9gqm38n_b8h0000gp/T/openclaw-502/openclaw-2026-04-14.log
Command: /opt/homebrew/opt/node@22/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 19789
Service file: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Service env: OPENCLAW_GATEWAY_PORT=19789
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
Gateway: bind=loopback (127.0.0.1), port=19789 (service args)
Probe target: ws://127.0.0.1:19789
Dashboard: http://127.0.0.1:19789/
Probe note: Loopback-only gateway; only local clients can connect.
Runtime: running (pid 59957, state active)
Warm-up: launch agents can take a few seconds. Try again shortly.
RPC probe: failed
RPC target: ws://127.0.0.1:19789
gateway closed (1006):
Gateway port 19789 is not listening (service appears running).
Last gateway error: 2026-04-14T21:34:31.608-04:00 Gateway start blocked: existing config is missing gateway.mode. Treat this as suspicious or clobbered config. Re-run openclaw onboard --mode local or openclaw setup, set gateway.mode=local manually, or pass --allow-unconfigured.
Logs: ~/.openclaw/logs/gateway.log
Errors: ~/.openclaw/logs/gateway.err.log
This still shows the same problem, which means gateway.mode is still not actually present in config.
Letās verify the raw gateway section directly.
Run this
openclaw config get gateway --json
If mode is missing, then immediately run:
openclaw config set gateway.mode local
openclaw config set gateway.bind loopback
openclaw config set gateway.port 19789 --strict-json
openclaw config set gateway.auth.mode token
openclaw config get gateway --json
openclaw gateway restart
openclaw gateway status --deep
What I want to see
In openclaw config get gateway --json, there should be a real field like:
"mode": "local"
Right now, the status output is telling us that field is still absent, so I want to catch whether:
- the
config setnever stuck - or something is deleting it immediately afterward
Paste the openclaw config get gateway --json output first, thatās the cleanest next clue.
heidi@Kates-Mac-mini ~ % openclaw config get gateway --json
{
"port": 19789,
"mode": "local",
"bind": "loopback",
"auth": {
"mode": "token",
"token": "OPENCLAW_REDACTED"
}
}
Good, that changes the diagnosis.
Your gateway config is actually correct now:
mode: localbind: loopbackport: 19789auth.mode: token
So that missing gateway.mode line is probably a stale last-error message, not the current root cause.
Next step: get the real current crash
Please paste these:
tail -100 ~/.openclaw/logs/gateway.err.log
tail -100 ~/.openclaw/logs/gateway.log
Why
Now we know:
- config is fine
- service starts
- port never binds
So the real problem is almost certainly in startup logs, for example:
- bad secret/provider config
- malformed
.env
- agent auth/profile parse failure
- some other runtime crash after config load
Weāre past the gateway-mode problem.
Now we need the actual live error from the logs.
heidi@Kates-Mac-mini ~ % tail -100 ~/.openclaw/logs/gateway.err.log
(node:61340) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ... to show where the warning was created)
2026-04-14T23:36:57.715-04:00 [secrets] [SECRETS_RELOADER_DEGRADED] SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
2026-04-14T23:36:57.718-04:00 Gateway failed to start: Error: Startup failed: required secrets are unavailable. SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
(node:61364) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ... to show where the warning was created)
2026-04-14T23:36:59.468-04:00 [secrets] [SECRETS_RELOADER_DEGRADED] SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
2026-04-14T23:36:59.469-04:00 Gateway failed to start: Error: Startup failed: required secrets are unavailable. SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
(node:61388) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ... to show where the warning was created)
2026-04-14T23:37:01.208-04:00 [secrets] [SECRETS_RELOADER_DEGRADED] SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
2026-04-14T23:37:01.209-04:00 Gateway failed to start: Error: Startup failed: required secrets are unavailable. SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
(node:61412) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ... to show where the warning was created)
There it is.
The gateway is failing because Agent 1 (heidi) still depends on:
ANTHROPIC_API_KEY
and that env var is now missing/empty.
What happened
You likely added ANTHROPIC_API_KEY_AGENT2, but heidi is still wired to the original:
ANTHROPIC_API_KEY
So startup fails before the gateway can bind the port.
Fix
Edit:
nano ~/.openclaw/.env
Make sure it contains both of these, if both agents should work:
ANTHROPIC_API_KEY=PASTE_HEIDI_KEY_HERE
ANTHROPIC_API_KEY_AGENT2=PASTE_AGENT2_KEY_HERE
Then restart:
openclaw gateway restart
openclaw gateway status --deep
Short version
heidistill needsANTHROPIC_API_KEYagent2can useANTHROPIC_API_KEY_AGENT2- right now the first one is missing, so the whole gateway wonāt start
Honestly, this is good news, because now itās a concrete config problem, not ghost chaos.
I don't have Heidi's api key anymore. If I generate a new one will it mess everything up?
No, generating a new one is totally fine, and honestly itās the right move here.
It wonāt mess up your agent setup as long as you put the new key back under the same env var name:
ANTHROPIC_API_KEY=NEW_HEIDI_KEY_HERE
What to do
Edit:
nano ~/.openclaw/.env
Make sure it has:
ANTHROPIC_API_KEY=NEW_HEIDI_KEY_HERE
ANTHROPIC_API_KEY_AGENT2=YOUR_AGENT2_KEY_HERE
Then restart:
openclaw gateway restart
openclaw gateway status --deep
Important
You do not need to recreate:
- the
heidiagent
- bindings
- Telegram config
Youāre just restoring the secret that heidi already points to.
Short version
- new Heidi key? safe
- put it back in
ANTHROPIC_API_KEY - restart gateway
- done
If you want, once youāve generated it, I can give you the exact final sanity-check commands.
š¦ OpenClaw 2026.4.14 (323493f) ā Your terminal just grew clawsātype something and let the bot pinch the busywork.
Restarted LaunchAgent: gui/502/ai.openclaw.gateway
Timed out after 60s waiting for gateway port 19789 to become healthy.
Gateway process is running but port 19789 is still free (startup hang/crash loop or very slow VM startup).
Service runtime: status=running, state=active, pid=69217
Gateway port 19789 status: free.
Gateway restart timed out after 60s waiting for health checks.
Tip: openclaw gateway status --deep
Tip: openclaw doctor
heidi@Kates-Mac-mini ~ %
We need the new error now, because gateway restart still only tells us ādidnāt bindā, not why.
Please run these 2 and paste them:
tail -30 ~/.openclaw/logs/gateway.err.log
grep -n '^ANTHROPIC' ~/.openclaw/.env | sed 's/=.*$/=REDACTED/'
Why these
gateway.err.logtells us the actual current startup failure- the redacted
grepconfirms the env vars are really present in the file the gateway loads
Iām guessing one of these is true:
ANTHROPIC_API_KEYstill isnāt in~/.openclaw/.env
- itās there but malformed
- thereās now a second missing secret for another agent
Paste those two outputs and weāll pin it down fast.
tail -30 ~/.openclaw/logs/gateway.err.log
Yep, run that command and paste the output, plus this one too:
grep -n '^ANTHROPIC' ~/.openclaw/.env | sed 's/=.*$/=REDACTED/'
I need the results, not just the command, so I can see whether itās still:
- missing
ANTHROPIC_API_KEY - malformed
.env - or a different secret failing now
2026-04-14T23:49:03.892-04:00 [secrets] [SECRETS_RELOADER_DEGRADED] SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
2026-04-14T23:49:03.893-04:00 Gateway failed to start: Error: Startup failed: required secrets are unavailable. SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
(node:71905) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ... to show where the warning was created)
2026-04-14T23:49:05.633-04:00 [secrets] [SECRETS_RELOADER_DEGRADED] SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
2026-04-14T23:49:05.636-04:00 Gateway failed to start: Error: Startup failed: required secrets are unavailable. SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
(node:71929) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ... to show where the warning was created)
2026-04-14T23:49:07.388-04:00 [secrets] [SECRETS_RELOADER_DEGRADED] SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
2026-04-14T23:49:07.391-04:00 Gateway failed to start: Error: Startup failed: required secrets are unavailable. SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
(node:71953) [DEP0040] DeprecationWarning: The punycode module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ... to show where the warning was created)
2026-04-14T23:49:09.155-04:00 [secrets] [SECRETS_RELOADER_DEGRADED] SecretRefResolutionError: Environment variable "ANTHROPIC_API_KEY" is missing or empty.
2026-04-14T23:49:09.156-04:00 Gateway failed to start: Error: Startup failed: required secrets are unavailable. SecretRefResolutionError: Environment variable "
Yep, that confirms it, no ambiguity now:
ANTHROPIC_API_KEY is still missing or empty.
So the gateway will keep failing until that exact env var exists with a real value.
Do this now
1. Edit the env file
nano ~/.openclaw/.env
Make sure this line exists and has a real key after the =:
ANTHROPIC_API_KEY=PASTE_HEIDI_NEW_KEY_HERE
If you also want Agent 2 later, keep that too:
ANTHROPIC_API_KEY_AGENT2=PASTE_AGENT2_KEY_HERE
2. Verify the lines exist
grep -n '^ANTHROPIC' ~/.openclaw/.env | sed 's/=.*$/=REDACTED/'
You should see at least:
ANTHROPIC_API_KEY=REDACTED
3. Restart gateway
openclaw gateway restart
openclaw gateway status --deep
Important
Itās not enough to have āsome Anthropic key somewhereā.
heidi is specifically wired to:
ANTHROPIC_API_KEY
So that exact variable name must exist and must not be blank.
heidi@Kates-Mac-mini ~ % grep -n '^ANTHROPIC' ~/.openclaw/.env | sed 's/=.*$/=REDACTED/'
1:ANTHROPIC_API_KEY_heidi=REDACTED
2:ANTHROPIC_API_KEY_sage=REDACTED
Aha, thereās the mismatch.
Your env file has:
ANTHROPIC_API_KEY_heidiANTHROPIC_API_KEY_sage
But heidi is currently configured to look for the exact name:
ANTHROPIC_API_KEY
Fastest fix
Add an alias line that points Heidiās existing key to the exact name OpenClaw expects.
Run this:
printf 'ANTHROPIC_API_KEY=%s\n' "$(awk -F= '/^ANTHROPIC_API_KEY_heidi=/{sub(/^ANTHROPIC_API_KEY_heidi=/,""); print; exit}' ~/.openclaw/.env)" >> ~/.openclaw/.env
Then verify:
grep -n '^ANTHROPIC' ~/.openclaw/.env | sed 's/=.*$/=REDACTED/'
You should now see:
ANTHROPIC_API_KEYANTHROPIC_API_KEY_heidiANTHROPIC_API_KEY_sage
Then restart:
openclaw gateway restart
openclaw gateway status --deep
Cleaner long-term fix
Later, you can rewire heidi to use ANTHROPIC_API_KEY_heidi directly.
But right now, the fastest path is just to add the missing generic alias and get the gateway healthy again.
š¦ OpenClaw 2026.4.14 (323493f) ā I don't judge, but your missing API keys are absolutely judging you.
ā
ā
Service: LaunchAgent (loaded)
File logs: /var/folders/9v/5sxh2c254w7cq9gqm38n_b8h0000gp/T/openclaw-502/openclaw-2026-04-14.log
Command: /opt/homebrew/opt/node@22/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway --port 19789
Service file: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Service env: OPENCLAW_GATEWAY_PORT=19789
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json
Gateway: bind=loopback (127.0.0.1), port=19789 (service args)
Probe target: ws://127.0.0.1:19789
Dashboard: http://127.0.0.1:19789/
Probe note: Loopback-only gateway; only local clients can connect.
Runtime: running (pid 74227, state active)
RPC probe: ok
Listening: 127.0.0.1:19789
Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting
Nice, thatās it. Gateway is healthy again. š
Youāre back to:
RPC probe: ok- listening on
127.0.0.1:19789
Iād do 2 things right now
1. Back up the working config
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.working-backup
cp ~/.openclaw/.env ~/.openclaw/.env.working-backup
2. Stop changing gateway-level stuff
From here on out, only do:
- agent creation
- bindings
- per-agent secrets
Not setup, not gateway re-onboarding.
One cleanup note
Right now heidi is booting because of the fallback alias:
ANTHROPIC_API_KEY
Later, if you want it cleaner, reconfigure heidi to use ANTHROPIC_API_KEY_heidi directly.
But donāt touch that now unless you want more excitement.
If you want, next I can help you finish sage / Agent 2 without knocking over the gateway again.
And if this solved the main issue, please right-click the solution message ā Apps ā ā Mark Solution so Answer Overflow can index it.
Now I'm getting the Telegram error: Missing API key for provider "openai". Configure on gateway auth for that provider, then try again. This is in the sage (agent2) profile. She isconfigured for Anthropic onlyl.
That usually means one of 2 things:
sageis not actually using the Anthropic model you think it is- Telegram is not actually routed to
sage, so the message is hitting some other agent/default session that wants OpenAI
So I would not add an OpenAI key. Thatās probably the wrong fix.
Please paste these
openclaw models status --agent sage
openclaw agents list --bindings
What Iām expecting
We want to confirm both of these are true:
sagemodel =anthropic/claude-sonnet-4-6telegram:<your-sage-account-id>routes tosage
If either of those is wrong, OpenClaw can fall back into a default/OpenAI path and you get exactly this error.
Short version: this smells like model/routing drift, not āyou need OpenAI now.ā
š¦ OpenClaw 2026.4.14 (323493f) ā Give me a workspace and I'll give you fewer tabs, fewer toggles, and more oxygen.
Approved telegram sender 8660138479.
heidi@Kates-Mac-mini ~ % openclaw models status --agent sage
š¦ OpenClaw 2026.4.14 (323493f) ā I'm the reason your shell history looks like a hacker-movie montage.
Config : ~/.openclaw/openclaw.json
Agent dir : ~/.openclaw/agents/sage/agent
Default (agent): anthropic/claude-sonnet-4-6
Fallbacks (0) (defaults): -
Image model (defaults): -
Image fallbacks (0) (defaults): -
Aliases (0) : -
Configured models (0): all
Auth overview
Auth store : ~/.openclaw/agents/sage/agent/auth-profiles.json
Shell env : off
Providers w/ OAuth/tokens (0): -
- anthropic effective=profiles:~/.openclaw/agents/main/agent/auth-profiles.json | profiles=1 (oauth=0, token=0, api_key=1) | anthropic:default=sk-ant-a...QHohUAAA | env=sk-ant-a...9X4BlQAA | source=env: ANTHROPIC_API_KEY
- anthropic-openai effective=env:sk-ant-a...9X4BlQAA | env=sk-ant-a...9X4BlQAA | source=env: ANTHROPIC_API_KEY
OAuth/token status
- none
š¦ OpenClaw 2026.4.14 (323493f) ā Automation with claws: minimal fuss, maximal pinch.
Agents:
- main (default)
Workspace: ~/.openclaw/workspace
Agent dir: ~/.openclaw/agents/main/agent
Routing rules: 0
Routing: default (no explicit rules)
Providers:- telegram heidi: configured
- telegram sage: configured
- heidi
Workspace: ~/.openclaw/workspace-heidi
Agent dir: ~/.openclaw/agents/heidi/agent
Model: anthropic/claude-sonnet-4-6
Routing rules: 1
Routing: telegram heidi
Providers:- telegram heidi: configured
Routing rules: - telegram accountId=heidi
- telegram heidi: configured
- sage
Workspace: ~/.openclaw/workspace-sage
Agent dir: ~/.openclaw/agents/sage/agent
Model: anthropic/claude-sonnet-4-6
Routing rules: 0
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.
Yep, found it.
sage has 0 routing rules, so Telegram sage is still falling through to main.
Thatās why youāre getting weird provider behavior.
Fix the routing
Run:
openclaw agents bind --agent sage --bind telegram:sage
openclaw agents list --bindings
You want to see an explicit rule for:
telegram:sageāsage
One more important thing
Your models status --agent sage also shows sage is not truly isolated yet on auth.
Itās currently resolving Anthropic from the shared/default path:
source=env: ANTHROPIC_API_KEY- and even
mainās auth store shows up in the effective path
So there are really 2 issues:
- Routing is wrong ā fix with
agents bind - Auth is still shared ā fix later by rewiring
sagetoANTHROPIC_API_KEY_sage
Do this first
openclaw agents bind --agent sage --bind telegram:sage
That should stop Telegram sage from landing on main.
Both agents were successfully up and running on Telegram last night and this morning neither are responsive.
If both died at the same time, Iād start by assuming this is a gateway/channel-level problem, not two separate agent failures.
Please paste this bundle:
openclaw --version
whoami
openclaw gateway status --deep
openclaw channels status --probe
openclaw agents list --bindings
tail -50 ~/.openclaw/logs/gateway.err.log
Why these first
gateway status --deeptells us if the gateway itself is alivechannels status --probetells us if Telegram is connected/configured
agents list --bindingsconfirms the routing rules didnāt driftgateway.err.logcatches the real startup/runtime errorwhoamimatters here because earlier you were bouncing between different macOS users
My guess
Most likely one of these:
- gateway didnāt come back cleanly after reboot/sleep
- Telegram channel config/pairing drifted
- youāre in the wrong macOS user again
- a required secret/env var is missing, so gateway started badly
Docs if you want them handy:
Paste that bundle and Iāll narrow it fast.
Okay they both responded as soon as I "woke up" the computer they're living on. It's powered on at all times, but it seems like I need to login a user in order for them to be responsive and functional?
Yep, thatās very likely what youāre seeing.
On macOS, the normal OpenClaw service install is a LaunchAgent, which is user-session scoped. So:
- machine powered on ā enough
- logged-in macOS user session = what the agent actually lives inside
That means after sleep / logout / some wake states, things can look āonā but not actually be responsive until that user session is active again.
Short version
For your current setup, yes, a logged-in user is effectively required.
If you want it reliable 24/7
Youāve got 2 good options:
Option 1, easiest on the Mac mini
Use a dedicated macOS user for OpenClaw and keep it:
- auto-login enabled
- display allowed to sleep if you want
- system sleep disabled
Option 2, more robust
Move the always-on gateway/runtime to a Linux box / VPS / dedicated headless host.
Thatās the cleaner āagents stay alive no matter whatā architecture.
My recommendation
Since youāre already deep into this Mac mini setup:
- create or keep a dedicated OpenClaw macOS user
- let that user stay logged in
- disable system sleep
If you want, I can give you the exact macOS settings checklist for making this box behave like an always-on agent host.
Yes please!
Yep, hereās the practical Mac mini checklist.
Best setup for an always-on OpenClaw Mac mini
1. Use one dedicated macOS user for OpenClaw
- keep both agents under that same logged-in user if youāre using the shared-gateway setup
- donāt bounce between macOS users unless you intentionally want separate runtimes
2. Enable automatic login for that user
In System Settings ā Users & Groups ā Automatic login
Set it to the dedicated OpenClaw user.
That way after reboot, the user session actually starts.
3. Disable system sleep
You want:
- display can sleep
- computer/system should not sleep
On a Mac mini, look in System Settings ā Lock Screen / Energy and make sure the machine itself stays awake.
If you use terminal, this is the behavior you want:
- no idle system sleep
- wake for network access on
- restart automatically after power failure on
4. Itās okay to lock the screen
The important part is:
- logged in = good
- logged out / sitting at login window = bad for this setup
So locked is usually fine, logged out is not.
5. Keep it on power and prevent surprise sleep
- plugged into power full time
- disable aggressive energy-saving stuff
- if itās a āheadlessā Mac mini, consider a dummy HDMI plug if display/wake behavior gets weird
6. Test it like a server
After you set this up, do a real test:
- reboot the Mac
- wait for auto-login
- do not manually open anything
- then check:
openclaw gateway status --deep
openclaw channels status --probe
My recommendation
For your current situation:
- one dedicated macOS user
- auto-login enabled
- system sleep off
- shared gateway on that user
If you eventually want true ānobody logs in everā server behavior, Iād move the gateway to Linux/VPS instead.
If you want, I can give you the exact terminal commands to make the Mac mini stay awake like a little crustacean server.
A dummy HDMI is a tiny plug you stick into the Macās HDMI port that pretends a monitor is connected.
People also call it:
- HDMI emulator
- headless display adapter
- ghost display plug
Why people use it
On headless Macs, it can help with weird behavior around:
- wake/sleep
- display detection
- remote access
- apps/services that behave better when macOS thinks a screen exists
In your case
You probably donāt need it unless the Mac mini is running with no real monitor and gets weird after sleep/wake.
So itās more of a stability hack for headless Macs, not an OpenClaw requirement.
Sorry, super simply:
A dummy HDMI is a little fake monitor plug.
You put it in the Mac miniās HDMI port so the Mac thinks a screen is attached, even when there isnāt one.
People use it for headless Macs because sometimes macOS behaves more reliably that way after sleep/wake or remote access.
So:
- Mac mini with real monitor attached ā probably donāt need it
- Mac mini with no monitor attached ā sometimes helpful
If you want, I can stop talking about dummy HDMI and give you the exact always-on Mac mini settings instead.
I am getting an error from Heidi in Telegram: HTTP 401: authentication_error: invalid x-api-key
Thatās actually a cleaner error than before.
It means Heidi is reaching the provider, but the key being used is invalid.
So this is no longer a gateway/routing problem, itās just bad Anthropic key material.
Most likely cause
heidi is still using:
ANTHROPIC_API_KEY
and that value is either:
- old
- mistyped
- revoked
- or not the same as your new valid Heidi key
Fix
Edit:
nano ~/.openclaw/.env
Make sure Heidiās lines both contain the same current valid key:
ANTHROPIC_API_KEY=YOUR_NEW_VALID_HEIDI_KEY
ANTHROPIC_API_KEY_heidi=YOUR_NEW_VALID_HEIDI_KEY
Then restart:
openclaw gateway restart
openclaw gateway status --deep
Important
Because Heidi is currently wired to the generic alias, updating only ANTHROPIC_API_KEY_heidi is not enough if ANTHROPIC_API_KEY still points at an old/bad key.
So for now, keep them identical.
If you want, after that I can help you do the clean final cleanup so Heidi uses ANTHROPIC_API_KEY_heidi directly and Sage uses ANTHROPIC_API_KEY_sage directly.