#multiple overlapping configs/profiles causing gateway issues
1 messages · Page 1 of 1 (latest)
You’re not crazy — what you’re describing is exactly what happens when the Gateway service and your CLI are accidentally pointing at different state dirs / config paths (most often because of a past gateway install done under a different --profile).
Mental model (the intended separation)
1) Profile (--profile main) = “which instance of OpenClaw on this host?”
A profile primarily scopes state + config:
OPENCLAW_STATE_DIR→ defaults to~/.openclaw-mainOPENCLAW_CONFIG_PATH→ defaults to~/.openclaw-main/openclaw.json
(Profiles are the recommended way to run multiple isolated gateways on one host.)
Docs: https://docs.openclaw.ai/gateway/multiple-gateways
2) Workspace (agents.defaults.workspace) = “where your agent files live”
This is where AGENTS.md, MEMORY.md, memory/, etc live. It’s separate from state dir.
So yes: you can absolutely have:
- config/state:
~/.openclaw-main/... - workspace:
~/clawd
Docs: https://docs.openclaw.ai/help/faq#where-does-openclaw-store-its-data
3) “project-level ~/clawd/openclaw.json” is not a thing unless you explicitly wire it
OpenClaw does not auto-read config from your workspace. It reads from $OPENCLAW_CONFIG_PATH (defaulting to the profile’s state dir).
So ~/clawd/openclaw.json is ignored unless you set OPENCLAW_CONFIG_PATH=~/clawd/openclaw.json.
Docs: https://docs.openclaw.ai/help/faq#what-format-is-the-config-where-is-it
Why you’re seeing unauthorized: gateway token missing/mismatch
That specific symptom almost always means:
- the gateway process you’re connecting to has auth enabled and expects a token, but
- the CLI you’re running didn’t send one (or sent a different one)
…and the most common reason is: the systemd user service is running a different config than the CLI.
The FAQ calls this out directly and the fix is to reinstall the service from the profile you actually want:
Docs: https://docs.openclaw.ai/help/faq#why-does-openclaw-gateway-status-show-config-cli-and-config-service-different
The clean “one deterministic setup” recipe (Profile = main, Workspace = ~/clawd, Port = 18789)
- Confirm version first (important for troubleshooting):
openclaw --version
- Make sure the
mainprofile config sets your workspace + token:
openclaw --profile main config set agents.defaults.workspace "~/clawd"
openclaw --profile main config get gateway.auth.token
If gateway.auth.token is empty/missing, generate one:
openclaw --profile main doctor --generate-gateway-token
- Re-install the gateway service under the same profile (this is the key step):
openclaw --profile main gateway install --force
openclaw --profile main gateway restart
- Verify you’re probing the right gateway and it’s using the expected config:
openclaw --profile main gateway status
openclaw --profile main health --verbose
If you also previously installed a non-profile service (default ~/.openclaw) it can keep coming back at boot and “fight” you. The easiest way to detect that is:
openclaw gateway status --deep
openclaw --profile main gateway status --deep
(You don’t need to delete any directories to fix this; it’s usually just “service installed pointing at the wrong place”.)
One important clarification about gateway.remote.token
From the remote docs:
gateway.auth.token= what the Gateway expectsgateway.remote.token= what the CLI uses for remote-mode defaultsgateway.remote.tokendoes not enable local auth by itself
Docs: https://docs.openclaw.ai/gateway/remote#cli-remote-defaults
So for a single local gateway, the “token that matters” is gateway.auth.token.
If you want “different Telegram channels → different personas/workspaces”
You probably want multi-agent routing inside one gateway instance (one profile), not separate gateway profiles (unless you truly want multiple isolated gateways).
Docs: https://docs.openclaw.ai/concepts/multi-agent
If you paste (redacted) output of these, I can tell you exactly which config/service is currently winning:
openclaw --version
openclaw gateway status --deep
openclaw --profile main gateway status --deep
openclaw --profile main config get agents.defaults.workspace
openclaw --profile main config get gateway.mode
That error is just the CLI telling you config set needs 2 args: a path and a value.
Docs: https://docs.openclaw.ai/cli/config
Examples (what you probably meant)
Set your workspace to ~/clawd (stored in the main profile config at ~/.openclaw-main/openclaw.json):
openclaw --profile main config set agents.defaults.workspace "~/clawd"
openclaw --profile main config get agents.defaults.workspace
Make sure the gateway token is actually set in that same config:
openclaw --profile main config get gateway.auth.token
If it’s empty/missing, generate one (only fills it if missing):
openclaw --profile main doctor --generate-gateway-token
openclaw --profile main config get gateway.auth.token
If you want to explicitly set/rotate it yourself:
openclaw --profile main config set gateway.auth.token "<paste-token-here>"
The common “why health says token missing” footgun
If you started the gateway with runtime flags/env (or some other profile), but your CLI is reading a config that doesn’t have gateway.auth.token, then openclaw --profile main health will connect with no token → unauthorized: gateway token missing.
So after setting the token, the “make it deterministic” step is to ensure the service is installed under the same profile:
openclaw --profile main gateway install --force
openclaw --profile main gateway restart
Can you paste these 3 outputs? (redact token value)
openclaw --profile main gateway status --deep
openclaw --profile main config get gateway.auth.token
openclaw --profile main health --verbose
That will show immediately whether the service and the CLI are still pointing at different configs/state dirs.
This output is actually good news: your CLI + service are using the same profile + same config path now:
- Config (cli):
~/.openclaw-main/openclaw.json - Config (service):
~/.openclaw-main/openclaw.json
So this is no longer an “overlapping configs” / token mismatch problem.
Right now the problem is simpler: the gateway is not staying up.
Runtime: stopped … last exit 1RPC probe: failed … gateway closed (1006)openclaw health --verbosefails because there’s no healthy WS server to talk to.
Next step: find why the service exits immediately
Please run these and paste the output (token already redacts fine):
journalctl --user -u openclaw-gateway-main.service -n 200 --no-pager
tail -n 200 /tmp/openclaw/openclaw-2026-02-16.log
Quick isolation test (foreground run)
This bypasses systemd and should print the real exception if it’s crashing on boot:
openclaw --profile main gateway run --port 18789 --verbose
If that works in the foreground but systemd still dies, then it’s almost always a service/env/runtime mismatch, and the fix is usually:
openclaw --profile main doctor --repair
openclaw --profile main gateway install --force
openclaw --profile main gateway restart
One more important note
You’re on 2026.2.12. There’s a known nasty bug in that release that can cause weird session/store path failures after restart (fixed on 2026.2.13). So if the logs show something like session path / store validation exploding, upgrading to ≥ 2026.2.13 is likely part of the fix.
Paste the journalctl + tail output and we’ll know immediately which branch this is (port bind, config parse, node/runtime path, or that 2026.2.12 bug).
journalctl + tail is too long what do you suggest
You don’t need the whole thing — we just need the crash signature (the first real error/stacktrace), usually ~20–80 lines.
Try these “short + high-signal” slices:
1) systemd summary (often enough by itself)
systemctl --user status openclaw-gateway-main.service --no-pager -l
2) journalctl, last 80 lines (clean output)
journalctl --user -u openclaw-gateway-main.service -b -n 80 --no-pager -o cat
3) file log: last 120 lines
tail -n 120 /tmp/openclaw/openclaw-2026-02-16.log
4) If even that’s noisy: grep for the “needle”
Pick one of these and paste the output:
grep -nEi "fatal|error|exception|EADDRINUSE|GatewayLock|unauthorized|token|Session file path|ENOENT|EACCES" \
/tmp/openclaw/openclaw-2026-02-16.log | tail -n 50
If you paste (1) + (2) I can usually tell exactly why it’s exiting (config parse, port bind, bad Node path, that 2026.2.12 session-path bug, etc.).
Nice — it’s running now. The key clue in that output is:
Active: active (running)- but also
restart counter is at 57→ it was crash-looping/flapping and systemd kept restarting it.
So the next step is: check whether it stays up long enough for the CLI to connect, and if it still flaps, grab just the error lines from the journal.
1) Re-run health now (while it’s “active”)
openclaw --profile main health --verbose
2) Confirm the gateway probe works + see “Last gateway error”
openclaw --profile main gateway status
3) If it still disconnects / keeps restarting: extract only the error-ish journal lines
This avoids the “too long” problem:
journalctl --user -u openclaw-gateway-main.service -b --no-pager -o cat \
| grep -Ei "error|fatal|exception|EADDRINUSE|GatewayLock|unauthorized|token|Session file path|EACCES|ENOENT" \
| tail -n 80
That grep-tail is usually enough to pinpoint whether it’s:
- port bind conflict (
EADDRINUSE/GatewayLock) - config parse/validation crash
- the known 2026.2.12 session-path bug
- permissions / missing file
If you paste the output of (1) + (2), and if needed the filtered journal from (3), we can zero in fast.
That 1006 abnormal closure almost always means: the WS connection is getting dropped because the gateway process is crashing/restarting mid‑handshake (vs an auth error, which usually shows unauthorized / 401 / 1008).
And your systemctl status already hints at that: restart counter = 57 → it’s been flapping.
To keep the paste short, grab only the last couple minutes + only “error-ish” lines:
1) Is it still restarting right now?
systemctl --user show openclaw-gateway-main.service -p ActiveState -p SubState -p NRestarts --no-pager
2) Journal: last 2 minutes, then filter to the useful bits
journalctl --user -u openclaw-gateway-main.service --since "2 min ago" --no-pager -o cat \
| grep -Ei "error|fatal|exception|EADDRINUSE|GatewayLock|unauthorized|token|Session file path|EACCES|ENOENT|config" \
| tail -n 120
3) File log: filter similarly (often even cleaner)
grep -nEi "error|fatal|exception|EADDRINUSE|GatewayLock|unauthorized|token|Session file path|EACCES|ENOENT|config" \
/tmp/openclaw/openclaw-2026-02-16.log | tail -n 120
Paste outputs of (1) + either (2) or (3).
Why I’m asking for “Session file path…”
You’re on 2026.2.12, which has a known crashy bug around session store paths (Session file path must be within sessions directory) that was fixed in 2026.2.13. If your filtered logs show that string, the fix is basically “upgrade to ≥ 2026.2.13”.
If you don’t see that string, the filtered logs will still tell us the real cause (port conflict, config parse error, missing permission, etc.).
Stop the crash-loop first, then upgrade the CLI, then re-run Doctor + reinstall the service under the same profile.
0) Stop the flapping service (so it isn’t restarting mid-upgrade)
Either one is fine:
openclaw --profile main gateway stop
# or:
systemctl --user stop openclaw-gateway-main.service
1) Upgrade OpenClaw (recommended path)
This keeps your ~/.openclaw-main config/state and just upgrades the code:
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-onboard
Alternative (if you know you installed globally via npm/pnpm):
npm i -g openclaw@latest
# or:
pnpm add -g openclaw@latest
Then confirm you’re no longer on 2026.2.12:
openclaw --version
2) Repair/migrate + re-install the systemd unit for the profile
Run this under the profile you actually use:
openclaw --profile main doctor --repair
openclaw --profile main gateway install --force
openclaw --profile main gateway restart
3) Verify it’s stable now
openclaw --profile main gateway status
openclaw --profile main health --verbose
If you paste your openclaw --version after step (1), I can tell you if you landed on the version that contains the 2026.2.12 crash fix.
Cool, you’re on 2026.2.14 now — so we’ve likely moved past the 2026.2.12-specific bug. The reason health still fails is simply: the gateway service is still crash-looping (ActiveState=activating / auto-restart earlier, and last exit 1).
The fastest “high-signal” next step is to check one config value that will make the gateway exit immediately:
1) Check if your profile is accidentally in remote mode
If gateway.mode is remote, the service will start openclaw gateway … and then immediately refuse/exit.
Run:
openclaw --profile main config get gateway.mode
openclaw --profile main config get gateway.remote.url
If you see remote, fix it:
openclaw --profile main config set gateway.mode "local"
openclaw --profile main gateway restart
2) Get the crash reason without huge logs (last 60 lines only)
This is usually enough to catch the actual exception / config parse error:
journalctl --user -u openclaw-gateway-main.service -n 60 --no-pager -o cat
Or from the file log (also short):
tail -n 80 /tmp/openclaw-1000/openclaw-2026-02-16.log
Paste whichever of those is shorter, plus the output of gateway.mode. That should pinpoint the exact exit-1 cause in one shot.
Those messages mean the keys aren’t present in your config file, not that the keys don’t exist.
And this is very likely exactly why your gateway service is exiting with code 1: the Gateway refuses to start unless gateway.mode is explicitly set to "local" (unless you run with --allow-unconfigured, which the systemd service does not).
Do this:
openclaw --profile main config set gateway.mode "local"
openclaw --profile main config set gateway.bind "loopback"
# optional, since your service already passes --port 18789:
openclaw --profile main config set gateway.port 18789 --json
Then restart:
openclaw --profile main gateway restart
openclaw --profile main gateway status
openclaw --profile main health --verbose
If you want the “one command that migrates/fixes missing defaults” path (recommended after upgrades):
openclaw --profile main doctor --repair
openclaw --profile main gateway restart
If after setting gateway.mode it still crash-loops, paste just:
journalctl --user -u openclaw-gateway-main.service -n 60 --no-pager -o cat
Yep — those journal lines are the smoking gun:
Gateway start blocked: set gateway.mode=local (current: unset)
Your systemd unit runs openclaw … gateway without --allow-unconfigured, so it will always exit until gateway.mode is explicitly set to "local" in ~/.openclaw-main/openclaw.json.
Run this exact sequence:
# stop the crash loop (optional but makes the output calmer)
systemctl --user stop openclaw-gateway-main.service
# set the required config key
openclaw --profile main config set gateway.mode "local"
# verify it stuck
openclaw --profile main config get gateway.mode
# start again
systemctl --user start openclaw-gateway-main.service
# or: openclaw --profile main gateway restart
Then check:
openclaw --profile main gateway status
openclaw --profile main health --verbose
If config set errors for any reason, paste that error + the first ~20 lines of ls -la ~/.openclaw-main/ (no secrets needed). Docs reference for the key (and why it’s required): https://docs.openclaw.ai/gateway/configuration#gateway
Your current output looks healthy now — the gateway is up and the CLI can talk to it:
Runtime: running …RPC probe: okopenclaw --profile main health --verbosereturns a normal snapshot (no auth errors)
So whatever “security settings” you set last week aren’t blocking the CLI anymore; the real blocker was exactly what the journal showed earlier: gateway.mode was unset, and the service refuses to start unless it’s local.
Next steps (make it clean + deterministic)
1) Lock in ~/clawd as the workspace for the main profile
Right now your state dir is correct (~/.openclaw-main), but we still need to ensure the workspace is what you want:
openclaw --profile main config get agents.defaults.workspace
openclaw --profile main config set agents.defaults.workspace "~/clawd"
(That’s the intended separation: state/config under ~/.openclaw-main, workspace wherever you want.)
2) Confirm your gateway is “local mode” + auth token is set (sanity)
openclaw --profile main config get gateway.mode
openclaw --profile main config get gateway.auth.mode
openclaw --profile main config get gateway.auth.token # redact when pasting
openclaw --profile main config get gateway.bind
3) Check you don’t have another gateway service running (the classic “colliding profiles” thing)
openclaw gateway status --deep
systemctl --user list-units 'openclaw-gateway*'
If you see multiple enabled services, disable the ones you don’t use (don’t delete dirs yet — just stop/disable first).
4) Ignore (for now) the “nvm / out of date service” warning
That warning is basically: “your systemd unit points at an NVM Node path; if that Node install disappears, the service breaks.” It’s not what’s breaking you right now (since the gateway is running).
When you’re ready to clean that up, the supported path is:
openclaw --profile main doctor --repair
openclaw --profile main gateway install --force
(Doctor will keep nudging you toward a “system Node 22+” install so the service isn’t tied to NVM.)
If you paste the output of (1) and (3) (workspace + deep status), I can tell you if anything is still overlapping and what to disable to get to “one profile, one gateway, one workspace.”
You’re basically fixed now — the important lines are:
Runtime: running …RPC probe: ok- health output works
What you’re seeing now is just the “leftovers” from the old default (no-profile) instance colliding with your new --profile main instance.
What’s happening (and why it looks like “security settings”)
When you run:
openclaw gateway status --deep
(without --profile main) the CLI uses the default profile state/config:
- Config (cli):
~/.openclaw/openclaw.json - Service file:
openclaw-gateway.service(disabled)
That default profile has an old/stale device token, so when it tries to probe the gateway that’s currently running on 18789 (your main gateway), it gets:
unauthorized: device token mismatch
That’s not your main gateway being broken — it’s just the wrong profile trying to talk to the right gateway with the wrong identity.
Next steps (recommended)
1) Restart the main gateway (you changed workspace)
You already got the hint “Restart the gateway to apply”:
openclaw --profile main gateway restart
openclaw --profile main health --verbose
2) (Optional) Make gateway.bind explicit (it’s fine that it was missing)
Missing gateway.bind just means “use defaults” (and your service args show loopback anyway). If you want it deterministic in config:
openclaw --profile main config set gateway.bind "loopback"
openclaw --profile main gateway restart
3) Stop confusing yourself: pick one “default”
Right now, you must remember to include --profile main, otherwise you fall back to the old default ~/.openclaw world.
Two easy fixes:
- Add to your shell profile (
~/.bashrc,~/.profile, etc.):export OPENCLAW_PROFILE=main - Or add an alias:
alias oc='openclaw --profile main'
4) Clean up the old default gateway service (no-profile)
Since openclaw-gateway.service is disabled/stopped and you’re not using it, uninstall it to reduce noise:
openclaw gateway uninstall
(That targets the no-profile service.)
Don’t delete ~/.openclaw yet unless you’re sure you don’t need anything in there — but uninstalling the service is safe and reversible.
If you run these two and paste output, I can confirm you’re down to “one gateway, one profile” cleanly:
openclaw --profile main gateway status
systemctl --user list-unit-files 'openclaw-gateway*'
Right now you don’t have a running Gateway service for the main profile.
The giveaway is:
systemctl --user list-unit-files 'openclaw-gateway*'shows onlyopenclaw-gateway.service(the no-profile/default unit)- there’s no
openclaw-gateway-main.serviceanymore openclaw --profile main gateway statusshowsService: systemd (disabled)andRuntime: stopped
So the fix is: re-install the per-profile systemd unit for main, then start it.
Do this
openclaw --profile main doctor --repair
openclaw --profile main gateway install --force
openclaw --profile main gateway start
Then verify:
systemctl --user status openclaw-gateway-main.service --no-pager -l
openclaw --profile main health --verbose
Optional cleanup (to avoid future confusion)
Once openclaw-gateway-main.service is running fine, you can remove the old default unit:
openclaw gateway uninstall
(that’s the no-profile one: openclaw-gateway.service)
If you paste the output of systemctl --user status openclaw-gateway-main.service --no-pager -l after install/start, I’ll sanity-check it.
Yep — that’s expected behavior if your active profile is main (either because you passed --profile main earlier a lot, or you exported OPENCLAW_PROFILE=main).
openclaw gateway uninstall always uninstalls the service for the currently-selected profile:
- profile = (none/default) →
openclaw-gateway.service - profile =
main→openclaw-gateway-main.service
Fix / next steps
1) Re-install the main service (since it got removed)
openclaw --profile main gateway install --force
openclaw --profile main gateway start
2) Uninstall the default (no-profile) service explicitly
Run the uninstall with the profile unset:
env -u OPENCLAW_PROFILE openclaw gateway uninstall
# (equivalently) OPENCLAW_PROFILE= openclaw gateway uninstall
3) Verify what’s installed
systemctl --user list-unit-files 'openclaw-gateway*'
If you paste that final list, I’ll confirm you ended up with only the main unit.
Perfect — you’re clean now.
- Only one unit exists:
openclaw-gateway-main.service - It’s enabled
Next sanity checks:
systemctl --user status openclaw-gateway-main.service --no-pager -l
openclaw --profile main health --verbose
And to avoid the “oops I ran a command without --profile main” issue going forward, I’d set:
export OPENCLAW_PROFILE=main
(in ~/.bashrc or ~/.profile), or alias openclaw to always include --profile main.
If everything’s stable now, please mark the solution in the thread (right‑click the helpful message → Apps → ✅ Mark Solution) so Answer Overflow indexes it.
That’s a clean win.
- systemd unit:
openclaw-gateway-main.serviceactive (running) - gateway is listening on
ws://127.0.0.1:18789 openclaw --profile main health --verboseconnects fine- config path is consistently
~/.openclaw-main/openclaw.json - workspace is set to
~/clawd(and you restarted to apply)
Two “wrap it up” recommendations:
- Make
mainyour default so you don’t accidentally hit the (now removed) default profile:
echo 'export OPENCLAW_PROFILE=main' >> ~/.bashrc
# then new shell, or:
source ~/.bashrc
- If this fixed it, please mark the solution in the thread (right‑click the solution message → Apps → ✅ Mark Solution). This helps Answer Overflow index it for the next person.
Now help me create multiple profiles (keep /clawd/ as main and create a /re/ one in a separate channel)
You can do this two ways, and it matters which one you actually want:
Option A (recommended): one profile / one Gateway, multiple agents (workspaces) routed by Telegram chat
This gives you exactly “~/clawd is main, ~/re is separate, different Telegram chats go to different brains” without running multiple gateways.
1) Create the “re” agent + workspace
mkdir -p ~/re
openclaw --profile main agents add re --workspace ~/re
openclaw --profile main agents list
2) Route a specific Telegram chat to that agent
You need the Telegram chat id (group/channel id). Easiest way: send a test message in that Telegram chat and then look in logs for the peer id, or use openclaw directory … if it’s available for your Telegram setup.
Then add a binding in ~/.openclaw-main/openclaw.json (via openclaw --profile main configure, or openclaw --profile main config set … if you prefer CLI edits):
{
bindings: [
// Example: route a specific Telegram group/channel to the re agent
{
agentId: "re",
match: {
channel: "telegram",
peer: { kind: "group", id: "<TELEGRAM_CHAT_ID>" } // or kind: "channel"
}
}
]
}
Restart to apply:
openclaw --profile main gateway restart
openclaw --profile main agents list --bindings
Why this is better: you keep one gateway service, one port (18789), one Telegram bot token, and you just route chats.
Docs: https://docs.openclaw.ai/concepts/multi-agent
Option B: multiple profiles (multiple Gateways) on the same machine
Do this only if you truly want hard isolation (separate state dirs, separate ports, separate dashboards, separate services).
Important Telegram gotcha
Two gateways cannot reliably share the same Telegram bot token. If you run 2 gateways, you almost certainly need 2 Telegram bots/tokens (one per gateway), otherwise they’ll fight over updates/webhooks.
Steps for a new profile re
Pick a different port (leave ~20 port gap). Example: 19001.
openclaw --profile re setup --workspace ~/re
openclaw --profile re config set gateway.mode "local"
openclaw --profile re config set gateway.port 19001 --json
openclaw --profile re config set gateway.bind "loopback"
openclaw --profile re doctor --generate-gateway-token
openclaw --profile re gateway install --force
openclaw --profile re gateway start
openclaw --profile re health --verbose
Docs: https://docs.openclaw.ai/gateway/multiple-gateways
Quick question so I can steer you correctly
Do you want two gateways running at the same time (two dashboards, two ports, likely two Telegram bots)… or do you mainly want two separate workspaces/personas for different Telegram chats?
If it’s “different Telegram chats”, Option A (multi-agent routing) is almost always the cleanest.
Yes — multiple agents (“brains”) inside one Gateway is the preferred way to do this. Each agent has its own:
- workspace (
~/clawdvs~/re) → separateAGENTS.md/MEMORY.md/memory/… - per-agent auth + sessions under
~/.openclaw-main/agents/<agentId>/…
Then you can attach multiple Telegram bot accounts and route each bot to a different agent.
You already have the re agent + ~/re, so you’re 80% done.
Step 1 — create the 2nd Telegram bot (BotFather)
Create a new bot in Telegram via BotFather and copy the token. (This token should be different from your main bot.)
Step 2 — add the 2nd Telegram bot to OpenClaw as a new Telegram account
Run this on the gateway host:
openclaw --profile main channels add --channel telegram --account re --token "<BOTFATHER_TOKEN_FOR_RE>"
This writes config under channels.telegram.accounts.re.*.
(You can confirm it exists with openclaw --profile main config get channels.telegram.accounts.re.)
Step 3 — route that Telegram accountId to the re agent (bindings)
Since you currently have 0 routing rules, you can safely set bindings as a fresh array:
openclaw --profile main config set bindings '[
{"agentId":"re","match":{"channel":"telegram","accountId":"re"}}
]' --json
Everything else will continue to go to main by default.
Restart to apply:
openclaw --profile main gateway restart
Verify routing:
openclaw --profile main agents list --bindings
Step 4 — make sure the re agent has model credentials
Auth profiles are per-agent. Check:
openclaw --profile main models status --agent re
If it shows missing creds, re-run your auth setup but targeting that agent (same provider token/key you used for main, just stored under the re agent).
Step 5 — add the new bot to the Telegram chat/channel you want
Invite the new bot to the target group/channel and message it there (or /start in DM) to confirm it responds as the re brain.
If you paste your (redacted) openclaw --profile main agents list --bindings after step 3, I’ll sanity-check the routing.
Unknown channel: telegram means the Telegram channel plugin isn’t enabled in your profile yet.
Telegram is shipped as a bundled plugin (id: "telegram"), but it can be disabled until you enable it.
0) Enable the Telegram plugin (profile: main)
openclaw --profile main plugins enable telegram
openclaw --profile main gateway restart
Sanity check:
openclaw --profile main plugins list | grep telegram
1) Add your two Telegram bots as two accounts (same Gateway)
Pick account IDs (example: mainbot + rebot):
openclaw --profile main channels add --channel telegram --account mainbot --token "<TOKEN_MAIN_BOT>"
openclaw --profile main channels add --channel telegram --account rebot --token "<TOKEN_RE_BOT>"
This ends up in config like:
channels.telegram.accounts.mainbot.botTokenchannels.telegram.accounts.rebot.botToken
2) Route each Telegram account to a different “brain” (agent)
You already have agents main and re. Add bindings:
openclaw --profile main config set bindings '[
{"agentId":"main","match":{"channel":"telegram","accountId":"mainbot"}},
{"agentId":"re","match":{"channel":"telegram","accountId":"rebot"}}
]' --json
openclaw --profile main gateway restart
Verify:
openclaw --profile main agents list --bindings
openclaw --profile main channels status --probe
Is this the preferred way for “multiple brains with separate memories”?
Yes. Multiple agents is the intended “multiple brains” mechanism:
- separate workspaces (
~/clawdvs~/re) - separate sessions + per-agent auth under
~/.openclaw-main/agents/<agentId>/…
Running multiple profiles/gateways is heavier and usually only needed for hard isolation/redundancy.
One more gotcha (important)
Model/provider credentials are per-agent. After routing works, check:
openclaw --profile main models status --agent re
If re has no credentials, you’ll need to add them for that agent too.
If you paste the output of openclaw --profile main plugins list (just the lines around telegram), I can confirm it’s enabled and we’re using the right channel IDs.
Nice — that channels status --probe output means the hard part is done:
- Telegram account guerro is up and working (
@guerrothebot) - Telegram account re is up and working (
@agentramsey_bot)
Now you just need the bindings so each bot routes to the right brain.
1) Add bindings (route by Telegram accountId)
Run:
openclaw --profile main config set bindings '[
{"agentId":"main","match":{"channel":"telegram","accountId":"guerro"}},
{"agentId":"re","match":{"channel":"telegram","accountId":"re"}}
]' --json
Great — if both Telegram accounts show running … works, you’re ready for the last wiring step: bindings.
1) Add the routing rules (bindings)
This routes bot account guerro → agent main and bot account re → agent re:
openclaw --profile main config set bindings '[
{"agentId":"main","match":{"channel":"telegram","accountId":"guerro"}},
{"agentId":"re","match":{"channel":"telegram","accountId":"re"}}
]' --json
openclaw --profile main gateway restart
Verify:
openclaw --profile main gateway restart
Verify:
openclaw --profile main agents list --bindings
2) Make sure the re brain can actually use a model
Because model auth is per-agent:
openclaw --profile main models status --agent re
openclaw --profile main agents list --bindings
2) Confirm the re brain has model credentials
Auth is per-agent:
openclaw --profile main models status --agent re
If re is missing creds, add/copy the provider auth to that agent (otherwise the bot will receive messages but won’t be able to answer with a model).
3) Test in Telegram
- DM
@guerrothebot→ should use workspace~/clawd - DM
@agentramsey_bot→ should use workspace~/re
If it shows missing creds, you’ll need to add the same provider credential to agent re (usually easiest via whatever auth method you used for main, but targeting --agent re where supported).
3) Test
- DM
@guerrothebot→ should respond as main (workspace~/clawd) - DM
@agentramsey_bot→ should respond as re (workspace~/re)
For openclaw --profile main plugins list: paste the output (it’s usually short) and I’ll confirm telegram is enabled + nothing weird is duplicated.
If you get a reply but it’s clearly the “wrong brain”, paste openclaw --profile main agents list --bindings and we’ll spot the mismatch immediately.
Yes — auth is per-agent (per “brain”) by design.
That’s why the error points at:
~/.openclaw-main/agents/re/agent/auth-profiles.json
Each agent has its own auth store so you can keep things isolated (different provider keys, different budgets, different companies, etc.). But you absolutely can reuse the same Anthropic key/token — you just need to make it available to the re agent too.
Fastest way: copy the auth profiles from main → re
On the gateway host:
cp -a ~/.openclaw-main/agents/main/agent/auth-profiles.json \
~/.openclaw-main/agents/re/agent/auth-profiles.json
openclaw --profile main gateway restart
Then verify:
openclaw --profile main models status --agent re
Alternative (more “proper”, no file copying): add creds while targeting the re agent
There isn’t a super-obvious --agent re flag for models auth paste-token yet, so the supported workaround is usually either:
- re-run your auth flow in the context of the
reagent, or - use the copy method above (most people do this; it’s fine).
Do you have to set up models for each separately?
You have to set up auth per agent, yes.
But “separately” doesn’t mean “different keys” — you can reuse the same key/token in both agents (copying the auth-profiles.json is literally that).
Sanity check (so we don’t miss anything)
Run these and paste the output if re still fails:
openclaw --profile main models status --agent main
openclaw --profile main models status --agent re
Once re has creds, your two Telegram bots will truly behave like two separate brains with separate memories (~/clawd vs ~/re).
guerro@guerro-bot:~$ cp -a ~/.openclaw-main/agents/main/agent/auth-profiles.json
~/.openclaw-main/agents/re/agent/auth-profiles.json
cp: cannot stat '/home/guerro/.openclaw-main/agents/main/agent/auth-profiles.json': No such file or directory
guerro@guerro-bot:~$ ls ~/.openclaw-main/agents/
main re
guerro@guerro-bot:~$ ls ~/.openclaw-main/agents/main/
sessions
guerro@guerro-bot:~$ ls ~/.openclaw-main/agents/main/sessions/
guerro@guerro-bot:~$
Yep — by default, each agent (“brain”) has its own auth store on purpose (so you can keep keys/billing isolated).
But you can absolutely reuse the same Anthropic credential across agents. You’re just hitting a wrinkle: your main agent doesn’t currently have an agent/ dir on disk yet, so there’s nothing to copy from.
What to do (quick + deterministic)
1) Run Doctor once to migrate/create the per-agent directories
This usually creates ~/.openclaw-main/agents/main/agent/… and migrates any legacy single-agent auth:
openclaw --profile main doctor --repair
2) Find where your current auth profile file actually is
Run:
find ~/.openclaw-main -maxdepth 4 -name auth-profiles.json -print
You’ll likely see one of these:
-
New multi-agent path (ideal):
~/.openclaw-main/agents/main/agent/auth-profiles.json -
Legacy single-agent path (Doctor should migrate it):
~/.openclaw-main/agent/auth-profiles.json
3) Copy main → re (create dirs if needed)
If you got the new path:
mkdir -p ~/.openclaw-main/agents/re/agent
cp -a ~/.openclaw-main/agents/main/agent/auth-profiles.json \
~/.openclaw-main/agents/re/agent/auth-profiles.json
openclaw --profile main gateway restart
Then verify:
openclaw --profile main models status --agent re
Alternative (even simpler): use one shared env key for all agents
If you’re using an Anthropic API key, putting it in the profile state dir .env makes it available to all agents automatically:
cat >> ~/.openclaw-main/.env <<'EOF'
ANTHROPIC_API_KEY=...
EOF
openclaw --profile main gateway restart
(That’s “shared credential for all brains”; per-agent auth profiles is “separate keys per brain”.)
If you paste the output of the find … auth-profiles.json command (just the file paths), I’ll tell you exactly which copy command to run.
Yeah — model auth is per-agent (“brain”), unless you provide it via environment (which is shared by the whole Gateway process).
In your case the error is telling us: the re agent can’t see any Anthropic credential (no ANTHROPIC_API_KEY in the gateway service env, and no Anthropic entry in that agent’s auth-profiles.json).
Preferred way to “reuse the same key” across multiple brains
Put the key in the profile state dir .env, so systemd + all agents inherit it:
- Create/edit:
nano ~/.openclaw-main/.env
Add:
ANTHROPIC_API_KEY=sk-ant-...
- Restart:
openclaw --profile main gateway restart
- Verify both brains see it:
openclaw --profile main models status --agent main
openclaw --profile main models status --agent re
This is the cleanest “shared credential, separate memories” setup.
Why this likely happened: you probably had the key in the old state dir (e.g. ~/.openclaw/.env) before moving to profile main. Profile main uses ~/.openclaw-main, so it won’t see the old .env unless you copy it.
You can also literally copy the old env file if it exists:
cp ~/.openclaw/.env ~/.openclaw-main/.env
openclaw --profile main gateway restart
When would you not reuse?
If you want true separation (different Anthropic accounts/billing), then yes: you configure different creds per agent (that’s what per-agent auth stores are for).
If you paste the output of openclaw --profile main models status --agent re after adding the .env, we can confirm it’s picking up ANTHROPIC_API_KEY correctly.
That’s the same root cause as before: you ran the command without --profile main, so the CLI fell back to the default state dir:
- It’s clearly using:
Config: /home/guerro/.openclaw/openclaw.json - Not:
~/.openclaw-main/openclaw.json
…and that default profile has stale device auth → unauthorized: device token mismatch.
Fix right now
Use the main profile explicitly:
openclaw --profile main logs --follow
(Or for any command: openclaw --profile main …)
Make it stop happening (recommended)
Set the profile in your shell so you don’t accidentally hit ~/.openclaw again:
echo 'export OPENCLAW_PROFILE=main' >> ~/.bashrc
source ~/.bashrc
Then confirm:
echo "$OPENCLAW_PROFILE"
Optional: “defuse the landmine”
If you’re sure you don’t need the old default state dir anymore, you can move it out of the way (safer than deleting):
mv ~/.openclaw ~/.openclaw.BACKUP
That makes “oops I forgot --profile main” fail loudly instead of doing weird auth things.
If you want, paste echo $OPENCLAW_PROFILE and I’ll tell you if your shell is actually picking it up.