#Two docker containers running now after upgrading openclaw

1 messages · Page 1 of 1 (latest)

frail sluice
#

Hello, I run OpenClaw on digital ocean. I upgraded today and now I see two containers running. ALso my agent seems to have no recollection of crons or anything.

}openclaw@openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c369c471da7a openclaw-sandbox:bookworm-slim "sleep infinity" About an hour ago Up About an hour openclaw-sbx-agent-main-f331f052
eb1cb67dab24 openclaw-sandbox:bookworm-slim "sleep infinity" 3 days ago Up 3 days openclaw-sbx-agent-main-0d71ad7a

lone ravenBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

dim sparrowBOT
#

Those openclaw-sbx-* containers are agent sandbox containers (for tool execution). Seeing two after an upgrade usually just means: the Gateway created a new sandbox (new config/image hash), and the old one didn’t get pruned yet.

Recommended cleanup (don’t docker rm manually):

openclaw sandbox list
openclaw sandbox explain
openclaw sandbox recreate --agent main
# (or: openclaw sandbox recreate --all)

Docs: https://docs.openclaw.ai/cli/sandbox
(Per docs, old containers can stick around until idle pruning kicks in; recreate forces it.)


About “no recollection of crons”

Cron jobs are not model memory — they’re persisted by the Gateway under:
~/.openclaw/cron/jobs.json (by default). So if they “disappeared”, it’s usually because you’re now running the Gateway/CLI against a different state dir or different OS user than before.

frail sluice
#

Ok my container issue is resolved however I have a .openclaw/cron/jobs.json on my host but my agent doesn't know anything about it. How do I remedy that? What's the correct approach>?

dim sparrowBOT
#

Cron jobs aren’t something the model “remembers” — they’re loaded by the Gateway scheduler from the Gateway’s active state dir, and you manage them via openclaw cron … (not by asking the chat agent).

If you have a ~/.openclaw/cron/jobs.json on disk but openclaw cron list (or the agent) shows nothing, it almost always means one of these:

1) You’re looking at the wrong state dir (most common after upgrades)

The running Gateway might now be using a different $OPENCLAW_STATE_DIR (or a different --profile, or a different Linux user like root vs openclaw), so it’s reading a different cron/jobs.json.

Run and paste:

openclaw status
openclaw gateway status --deep
openclaw cron status
openclaw cron list

Those will usually reveal which instance/profile you’re actually talking to.

2) You restored/edited jobs.json while the Gateway was running

#

Per docs, the Gateway loads jobs.json into memory and writes it back on changes, so manual edits are only safe while the Gateway is stopped.

Correct restore flow:

openclaw gateway stop
# copy/restore the jobs.json into the *active* state dir’s cron/ folder
openclaw gateway start   # or: openclaw gateway restart
openclaw cron list

Docs (this exact “don’t edit while running” gotcha is called out):
https://docs.openclaw.ai/automation/cron-jobs (see “Where cron jobs are stored”)

3) Docker/containerized gateway mismatch

If you’re running the Gateway in Docker/Compose, the Gateway’s state dir is whatever you mounted into the container. A jobs.json on the host won’t matter unless it’s in the mounted state dir the container uses.


#

What’s the “correct approach” going forward?

  • Use the CLI to manage jobs: openclaw cron add/edit/list (don’t hand-edit jobs.json).
  • Only do file-level restores with the Gateway stopped.

If you paste the 4 command outputs above, I can tell you exactly which state dir your Gateway is using and where that jobs.json needs to live.

frail sluice
#

openclaw cron list shows the jobs but i can't run openclaw from within the container, should i be able to?

dim sparrowBOT
#

No — you shouldn’t expect openclaw to exist inside those openclaw-sbx-* containers.

Those are sandbox containers used to run tool execution (like exec, file ops, etc.) in isolation. They’re intentionally minimal (your docker ps even shows they just run sleep infinity) and they are not “the OpenClaw Gateway container” and don’t ship with the OpenClaw CLI.

So the correct mental model is:

  • Cron scheduler + job store (~/.openclaw/cron/jobs.json) live in the Gateway state dir on the host.
  • You manage/run cron jobs from the host via openclaw cron ….
  • When a cron job triggers an agent turn that uses tools, those tool actions may execute inside the sandbox container — but that does not mean the sandbox has openclaw installed.

When does this become a problem?

If one of your cron jobs (or agent instructions) is doing something like “run openclaw … via exec”, that will fail when the session is sandboxed, because openclaw isn’t in the sandbox.

Fix options:

  1. Don’t call the CLI from inside the agent; use the actual OpenClaw cron/session features instead (preferred).
  2. If you really need extra binaries inside the sandbox, install them via sandbox.docker.setupCommand, then openclaw sandbox recreate --agent main (docs explain this flow): https://docs.openclaw.ai/cli/sandbox
  3. Or disable sandboxing for that agent/session (if you intentionally want host execution).
#

If you paste one failing cron job’s “what it does” (or the output of openclaw cron runs --id <jobId> --limit 5), I can tell you which of the three applies cleanly.

frail sluice
#

Ok so how dow e deal with the problem that the Agent appears to be unaware of its crons even though openclaw cron list on the host returns this

}openclaw@openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01:~$ openclaw cron list

🦞 OpenClaw 2026.2.24 (df9a474) — I'm not saying your workflow is chaotic... I'm just bringing a linter and a helmet.

│
◇ Doctor warnings ─────────────────────────────────────────────────────────────────────────╮
│ │
│ - State dir migration skipped: target already exists (/home/openclaw/.openclaw). Remove │
│ or merge manually. │
│ │
├───────────────────────────────────────────────────────────────────────────────────────────╯
│
â—‡
ID Name Schedule Next Last Status Target Agent
da02e7cc-cd5a-4aa8-908e-8acd8d2881a6 daily-schedule cron 15 5 * * * @ America/Tor... in 11h 13h ago ok isolated default
b26d0590-4283-4d59-9859-57ba47be5dad daily-wrapup cron 45 16 * * 1-5 @ America/... in 23h 1h ago error isolated default

dim sparrowBOT
#

openclaw cron list is the source of truth here — so your Gateway does know about the jobs.

What’s usually happening when it feels like “the agent is unaware”:

1) “Isolated” cron runs don’t share your chat context (expected)

Both of your jobs show Target = isolated.

That means each run executes in its own cron:<jobId> session and starts “fresh” (no prior conversation). So if you ask in your normal chat “what crons do we have?” the model won’t remember unless it actively queries cron, and the isolated runs also won’t “teach” the main chat anything.

Docs (this is by design): https://docs.openclaw.ai/automation/cron-jobs

2) The agent can’t run openclaw inside the sandbox container (also expected)

Those openclaw-sbx-* containers are tool sandboxes and don’t include the CLI, so an agent turn that tries to do exec: openclaw cron list will fail.

If you want the agent to inspect/manage cron jobs from chat, the “correct” way is: have it use the built-in cron tool (Gateway RPC), not the openclaw binary via exec.

Quick sanity check

#

When you ask your agent something like “list my cron jobs”, does it:

  • say it can’t access cron / tools are restricted, or
  • try to run openclaw … via exec and fail, or
  • just hallucinate?

If it’s tool-restricted, you’ll need to adjust tool policy to allow the cron tool (often via group:automation) for that agent/session. The tool policy knobs are described here: https://docs.openclaw.ai/tools/multi-agent-sandbox-tools

3) If you want cron outputs to show up in your main chat

Use cron delivery (announce/webhook) or use main-session cron jobs (system-event style) instead of isolated. (Exact CLI flags vary—check openclaw cron --help.)


If you paste what the agent replies when you ask “what cron jobs are configured?” (and whether you’re asking in Discord group vs a DM), I can tell you which of the 3 cases you’re in and the minimal config change (if any).

frail sluice
#

Me: Tell me what crons you have setup.

Agent:
Zero. None.

  1. System Crontab (crontab -l): Empty.
  2. Heartbeat (HEARTBEAT.md): Empty (just comments).

If you had a daily wrap-up, it’s gone. It likely lived in the old container (openclaw-sbx-agent-main-0d71ad7a) that’s been running for 3 days.

Action Plan:

  1. Kill the zombie container (-0d71ad7a).
  2. Rebuild your daily wrap-up here.

Want me to handle the cleanup or the rebuild?

dim sparrowBOT
#

That agent reply is just wrong/hallucinated. It checked Linux crontab -l + HEARTBEAT.md and then invented a story about the old sandbox container. OpenClaw cron jobs are the Gateway scheduler and live in ~/.openclaw/cron/jobs.json (which your openclaw cron list is already reading correctly).

So the real issue is: your chat agent isn’t querying the Gateway cron tool, so it falls back to guessing.

Fix: allow + use the Gateway cron.* tool (don’t shell out)

OpenClaw exposes a Gateway API surface for cron: cron.list, cron.status, cron.add, … (docs: https://docs.openclaw.ai/automation/cron-jobs#gateway-api-surface)

If tool policy blocks the cron tool, the model can’t call cron.list, and you’ll get exactly this kind of “Zero. None.” nonsense.

  1. Inspect what the session is allowed to call:
openclaw sandbox explain
# or: openclaw sandbox explain --agent main

This shows the effective tool allow/deny (docs: https://docs.openclaw.ai/gateway/sandbox-vs-tool-policy-vs-elevated)

  1. In ~/.openclaw/openclaw.json, make sure cron is allowed by tool policy.
#

If you’re using an allowlist anywhere, add either cron or group:automation (which expands to cron + gateway):

{
  tools: {
    allow: ["group:automation"] // or just "cron"
    // and if you also have a sandbox tool allowlist:
    // sandbox: { tools: { allow: ["group:automation"] } }
  }
}

Then restart (or reload) the gateway:

openclaw gateway restart
#
  1. Now ask your agent something explicit like:

“Use the Gateway cron tool (cron.list) and tell me what jobs are configured.”

One more “gotcha” (expected behavior)

Your jobs are Target = isolated, so each run happens in a fresh cron:<jobId> session and won’t share “memory” with your main chat. That’s normal and by design.

If you want, paste openclaw config get tools and the output of openclaw sandbox explain --json and I’ll tell you exactly where cron is getting blocked in your setup.

frail sluice
#

openclaw gateway restart caused this recurring error

Feb 25 18:23:15 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332342]: 2026-02-25T18:23:15.106-05:00 - Port is in use but process details are unavailable (install lsof or run as an admin user).
Feb 25 18:23:15 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332342]: 2026-02-25T18:23:15.157-05:00 Gateway service status unknown; if supervised, stop it first.
Feb 25 18:23:15 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332342]: 2026-02-25T18:23:15.168-05:00 Tip: openclaw gateway stop
Feb 25 18:23:15 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332342]: 2026-02-25T18:23:15.177-05:00 Or: systemctl --user stop openclaw-gateway.service
Feb 25 18:23:15 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 systemd[1]: openclaw.service: Main process exited, code=exited, status=1/FAILURE
Feb 25 18:23:15 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 systemd[1]: openclaw.service: Failed with result 'exit-code'.
Feb 25 18:23:15 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 systemd[1]: openclaw.service: Consumed 5.637s CPU time.
Feb 25 18:23:25 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 systemd[1]: openclaw.service: Scheduled restart job, restart counter is at 11.
Feb 25 18:23:25 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 systemd[1]: Started openclaw.service - Openclaw Gateway Service.
Feb 25 18:23:28 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01

#

4:29 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 systemd[1]: Started openclaw.service - Openclaw Gateway Service.
Feb 25 18:24:32 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332468]: │
Feb 25 18:24:32 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332468]: ◇ Doctor warnings ─────────────────────────────────────────╮
Feb 25 18:24:32 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332468]: │ │
Feb 25 18:24:32 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332468]: │ - State dir migration skipped: target already exists │
Feb 25 18:24:32 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332468]: │ (/home/openclaw/.openclaw). Remove or merge manually. │
Feb 25 18:24:32 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332468]: │ │
Feb 25 18:24:32 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[332468]: ├───────────────────────────────────────────────────────────╯

dim sparrowBOT
#

That log means the service is in a restart loop because something is already listening on the Gateway port (usually 18789). openclaw cron list still working is a hint that an “old” gateway process is likely still running, so the new service instance can’t bind the port.

The CLI can’t tell you the PID because lsof isn’t installed (and/or you’re not root), so do this:

1) Identify what’s holding the port

On Ubuntu you can use ss (no install needed):

sudo ss -lptn 'sport = :18789'

Or install lsof and use that:

sudo apt-get update
sudo apt-get install -y lsof
#
sudo lsof -nP -iTCP:18789 -sTCP:LISTEN

That will show the PID + command.

2) Stop the other gateway instance

On VPSes the common footgun is having both a system service and a user service (or a manual foreground gateway) running.

Check and stop both possibilities:

# system service (your logs show systemd[1], so this is very likely)
sudo systemctl status openclaw.service
sudo systemctl stop openclaw.service
#
# also check for the newer/common unit name
sudo systemctl list-units --type=service | grep -i openclaw

# user service (if you ever installed it that way)
systemctl --user list-units --type=service | grep -i openclaw
systemctl --user stop openclaw-gateway.service 2>/dev/null || true

Then re-check the port:

sudo ss -lptn 'sport = :18789'

If it still shows a PID, paste that line here (it’ll say exactly which process it is). If it’s a stray node …openclaw… process not managed by systemd, you can stop it cleanly once you confirm what it is.

3) Start the gateway again

#

Once the port is free:

sudo systemctl start openclaw.service
# or: openclaw gateway start

If you paste the output of sudo ss -lptn 'sport = :18789' and sudo systemctl list-units --type=service | grep -i openclaw, I can tell you exactly which duplicate instance you’ve got running.

#

That “Doctor warnings: State dir migration skipped: target already exists (/home/openclaw/.openclaw)” is a big clue: you likely have two different state directories on disk (old + new), and the gateway tried to migrate into ~/.openclaw but refused to overwrite it.

Result: “split brain” symptoms — cron/jobs exist (so openclaw cron list works), but other pieces (sessions/channel state/agent workspace/tool policy) may be coming from a different state dir/profile/user than the one you think.

What to do (safe + correct approach)

1) Confirm which state dir the running service is using

Run:

openclaw gateway status --deep
openclaw status

You’re looking for the State dir / Config path / Port it reports.

Also inspect the systemd unit so we can see if it’s pinning OPENCLAW_STATE_DIR, OPENCLAW_CONFIG_PATH, --profile, or a non-default --port:

#
sudo systemctl cat openclaw.service

2) Find the “other” state dir that Doctor wanted to migrate from

Common places after upgrades / user changes:

  • /root/.openclaw (old runs as root)
  • /home/openclaw/.openclaw (new runs as openclaw user)
  • profile dirs like /home/openclaw/.openclaw-<profile> if you used --profile

Quick scan:

ls -la /home/openclaw | grep openclaw || true
sudo ls -la /root | grep openclaw || true
sudo find /home/openclaw /root -maxdepth 2 -type d -name ".openclaw*" 2>/dev/null
#

3) Pick ONE state dir to be authoritative, then merge/migrate

Best practice is: stop the gateway, back up, then merge or re-run migration.

sudo systemctl stop openclaw.service
# (optional but strongly recommended backup)
tar -czf ~/openclaw-state-backup.tgz ~/.openclaw

Then either:

  • Merge manually (copy missing bits from old state dir into the one the service uses), or
  • Let Doctor migrate by moving the target dir out of the way (ONLY once you know the source dir Doctor is migrating from).

I don’t want to guess which way is safest until we see your gateway status --deep + systemctl cat.

Separate note: the chat agent saying “Zero crons” is hallucination

That reply is not actually reading OpenClaw cron at all (it checked Linux crontab + HEARTBEAT.md). If you want the agent to answer correctly, it needs access to the Gateway cron API/tool (cron.list), and tool policy must allow it (often via group:automation). But first let’s get your service/state-dir consistent.

#

Paste:

  • openclaw gateway status --deep
  • sudo systemctl cat openclaw.service

…and I’ll tell you exactly which state dir you’re running from and the cleanest migration/merge path.

frail sluice
#

I apologize, Sy. The cron tool is currently unavailable in this runtime, despite being listed in the skills documentation.

My previous check using crontab -l (the system command) showed nothing. Since I cannot access the Gateway's internal cron manager directly, I can't see any jobs that might be stored there.

If you have a cron.list file in your workspace, I can read that. Otherwise, I'm flying blind on existing schedules.

Shall I look for a file, or would you like me to just set up a new daily wrap-up from scratch?

#

That's what my agent is saying now that's back up

#

And now I'm getting this error

Feb 25 19:19:31 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[337557]: 2026-02-26T00:19:31.847Z [diagnostic] lane task error: lane=main durationMs=4 error="FailoverError: Unknown model: google-gemini-cli/gemini-3-1-pro-preview"
Feb 25 19:19:31 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[337557]: 2026-02-26T00:19:31.849Z [diagnostic] lane task error: lane=session:agent:main:main durationMs=8 error="FailoverError: Unknown model: google-gemini-cli/gemini-3-1-pro-preview"

dim sparrowBOT
#

That reply from your agent is hallucinating / using the wrong “cron” concept.

OpenClaw cron jobs are Gateway cron (openclaw cron list), not Linux crontab -l, and they definitely don’t “live in the old sandbox container”. Your openclaw cron list output proves the Gateway sees them.

What’s actually happening is: the model runtime you’re chatting with does not have the cron tool available, so it can’t call cron.list and falls back to guessing.

Fix: make sure the cron tool is allowed by tool policy (especially when sandboxed)

On the host, run these and paste the output:

openclaw config get tools
openclaw sandbox explain --json

What we’re looking for is any allow/deny lists like:

  • tools.allow / tools.deny
#
  • tools.sandbox.tools.allow / tools.sandbox.tools.deny
  • (and/or per-agent overrides under agents.list[].tools...)

If you have an allowlist configured anywhere, you must include cron there. Per docs, the shorthand is:

If you’re not already using a custom allowlist

You can set it directly (warning: this overwrites the current value of that key):

openclaw config set tools.allow '["group:automation"]' --strict-json
# and if you have a sandbox allowlist too:
openclaw config set tools.sandbox.tools.allow '["group:automation"]' --strict-json
#

Then restart the gateway service (use whichever you’re actually running under):

sudo systemctl restart openclaw.service
# or: openclaw gateway restart

Test

Ask the agent something that forces the right mechanism:

“Call the Gateway cron tool cron.list and show me the jobs.”

If it still says “cron tool unavailable”, it’s 100% in tool filtering (global vs per-agent vs sandbox tool policy). The two outputs I asked for (config get tools + sandbox explain --json) will pinpoint exactly where it’s getting blocked.

frail sluice
#

And now I'm getting this error

Feb 25 19:19:31 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[337557]: 2026-02-26T00:19:31.847Z [diagnostic] lane task error: lane=main durationMs=4 error="FailoverError: Unknown model: google-gemini-cli/gemini-3-1-pro-preview"
Feb 25 19:19:31 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[337557]: 2026-02-26T00:19:31.849Z [diagnostic] lane task error: lane=session:agent:main:main durationMs=8 error="FailoverError: Unknown model: google-gemini-cli/gemini-3-1-pro-preview"

dim sparrowBOT
#

Two separate things going on there:

1) FailoverError: Unknown model: google-gemini-cli/gemini-3-1-pro-preview

That means your Gateway is trying to use a default model ref that it can’t resolve anymore (either the provider plugin isn’t enabled/logged-in, or that exact model id isn’t in the current catalog/allowlist).

On the host, run:

openclaw models status
openclaw models list

Then either:

Option A (quick fix): switch to any model that does show up in models list

#
openclaw models set <provider/model-from-models-list>
sudo systemctl restart openclaw.service

Docs: https://docs.openclaw.ai/cli/models

Option B (if you specifically want Gemini CLI OAuth)

That provider is behind a bundled plugin that may be disabled after an upgrade/state-dir shuffle. Enable + re-login:

openclaw plugins enable google-gemini-cli-auth
openclaw models auth login --provider google-gemini-cli --set-default

Then pick a model that appears in openclaw models list and openclaw models set ….

#

Reference: https://docs.openclaw.ai/concepts/model-providers (section “Google Vertex, Antigravity, and Gemini CLI”)

(Also: if you only have a Gemini API key, you usually want the google/* provider, not google-gemini-cli/*.)


2) Agent says “cron tool unavailable” / “no crons”

That’s not the Gateway being empty — it’s your chat model being unable to call cron.list, so it guesses and checks Linux crontab instead.

This is almost always tool policy filtering (often only in sandboxed/non-main sessions). To see what’s actually allowed, run:

openclaw sandbox explain --json
openclaw config get tools

If you have an allowlist anywhere (tools.allow or tools.sandbox.tools.allow), make sure it includes cron (shorthand: group:automation includes cron + gateway):

#

Docs: https://docs.openclaw.ai/gateway/sandbox-vs-tool-policy-vs-elevated


If you paste the output of:

  • openclaw models status
  • openclaw sandbox explain --json

…I can tell you exactly (a) why that Gemini model ref is “unknown” in your install, and (b) the exact config key that’s currently hiding the cron tool from your Discord session.

#

That error is coming from model resolution, not cron:

FailoverError: Unknown model: google-gemini-cli/gemini-3-1-pro-preview

Meaning: your gateway is configured to use a model ref that your current install can’t resolve (either the Gemini CLI auth plugin isn’t enabled/logged-in anymore, or that exact model id no longer exists / isn’t in your allowed catalog).

Get the gateway unstuck (fastest)

  1. See what the gateway thinks the default model is and what’s available:
openclaw models status
openclaw models list
  1. Set the default to something that appears in openclaw models list:
openclaw models set <provider/model-from-the-list>
#
sudo systemctl restart openclaw.service

Docs: https://docs.openclaw.ai/cli/models


If you specifically want google-gemini-cli/* (Gemini CLI OAuth)

That provider requires a bundled plugin + login. After upgrades / state-dir/profile changes, it’s common for this to silently be “missing”.

Run:

openclaw plugins enable google-gemini-cli-auth
openclaw models auth login --provider google-gemini-cli --set-default
openclaw models list --provider google-gemini-cli
#

Then set the model to one that actually shows up in that list (don’t guess the id).

Reference: https://docs.openclaw.ai/concepts/model-providers (section “Google Vertex, Antigravity, and Gemini CLI”)


One more gotcha: model allowlist

If you have agents.defaults.models set, it acts as an allowlist/catalog and can also make models “disappear” unexpectedly.

Check:

openclaw config get agents.defaults.model
openclaw config get agents.defaults.models

#

If you paste the output of openclaw models status + openclaw plugins list | grep -i gemini, I can tell you exactly whether this is “plugin missing” vs “model id changed” vs “allowlist hiding it”.

frail sluice
#

sandbox explain --json
│
◇ Doctor warnings │ │
│ - State dir migration skipped: target already exists (/home/openclaw/.openclaw). Remove
"docsUrl": "https://docs.openclaw.ai/sandbox",
"agentId": "main",
"sessionKey": "agent:main:main",
"mainSessionKey": "agent:main:main",
"sandbox": {
"mode": "all",
"scope": "agent",
"perSession": false,
"workspaceAccess": "rw",
"workspaceRoot": "/home/openclaw/.openclaw/sandboxes",
"sessionIsSandboxed": true,
"tools": {
"allow": [
"exec",
"process",
"read",
"write",
"edit",
"apply_patch",
"image",
"sessions_list",
"sessions_history",
"sessions_send",
"sessions_spawn",
"subagents",
"session_status"
],
"deny": [
"browser",
"canvas",
"nodes",
"cron",
"gateway",
"telegram",
"whatsapp",
"discord",
"irc",
"googlechat",
"slack",
"signal",
"imessage"
],
"sources": {
"allow": {
"source": "default",
"key": "tools.sandbox.tools.allow"
},
"deny": {
"source": "default",
"key": "tools.sandbox.tools.deny"
}
}
}
},
"elevated": {
"enabled": true,
"allowedByConfig": false,
"alwaysAllowedByConfig": false,
"allowFrom": {},
"failures": []
},
"fixIt": [
"agents.defaults.sandbox.mode=off",
"agents.list[].sandbox.mode=off",
"tools.sandbox.tools.allow",
"tools.sandbox.tools.deny",
"agents.list[].tools.sandbox.tools.allow",
"agents.list[].tools.sandbox.tools.deny",
"tools.elevated.enabled"
]
}

{
"allow": [
"group:automation"
],
"exec": {
"host": "gateway",
"security": "full",
"ask": "off"
}

dim sparrowBOT
#

Your sandbox explain --json output nails the root cause:

  • You’re running with sandbox.mode: "all" → even your main session is sandboxed (sessionIsSandboxed: true)
  • In the sandbox tool policy, cron and gateway are explicitly denied:
"deny": ["browser", ... , "cron", "gateway", ...]

When a tool is denied, OpenClaw doesn’t even expose it to the model, so the model literally can’t call cron.list and falls back to guessing (crontab -l, HEARTBEAT.md, etc.). That’s why it says “cron tool unavailable / zero crons”.

Remedy (keep sandboxing, but allow cron)

You need to change the sandbox tool policy, not the global one.

  1. Inspect current values (so you don’t overwrite blindly):
#
openclaw config get tools.sandbox.tools.allow
openclaw config get tools.sandbox.tools.deny
  1. Update them so:
  • cron + gateway are removed from deny
  • cron + gateway are added to allow (because your sandbox policy uses a non-empty allowlist)

You can do it either by adding the shorthand group, or explicit tools:

But you still must remove cron/gateway from the sandbox deny list, because deny always wins.

  1. Restart:
#

You currently have:

{ "allow": ["group:automation"], ... }

If that is truly your global tools.allow, it would (by design) restrict non-sandboxed sessions to basically just cron+gateway. That’s fine if intentional, but if you ever switch sandbox.mode away from "all", you may suddenly “lose” read/exec/... outside the sandbox.

If you paste the outputs of:

openclaw config get tools.sandbox.tools.allow
openclaw config get tools.sandbox.tools.deny

I’ll tell you the exact openclaw config set ... commands to apply with the minimal diff (no giant copy/paste arrays unless needed).

frail sluice
#

Feb 25 19:42:58 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[338579]: 2026-02-26T00:42:58.309Z [ws] closed before connect conn=5ff921d2-7433-4603-b43c-83a72e46b770 remote=::1 fwd=142.115.111.45 origin=https://147.182.147.133 host=147.182.147.133 ua=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 code=1008 reason=origin not allowed (open the Control UI from the gateway host or allow it in gateway.controlUi.allowedOrigins)
Feb 25 19:43:04 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[338579]: 2026-02-26T00:43:04.103Z [agent/embedded] embedded run agent end: runId=69854bda-7e57-43ea-98e0-9accc3af0eb9 isError=true error=An unknown error occurred
Feb 25 19:43:04 openclaw-ubuntu-s-2vcpu-4gb-120gb-intel-tor1-01 openclaw[338579]: 2026-02-26T00:43:04.393Z [telegram] sendMessage ok chat=8396489171 message=736

dim sparrowBOT
#

That log is the Control UI getting blocked by the Gateway’s origin allowlist:

code=1008 reason=origin not allowed … allow it in gateway.controlUi.allowedOrigins
origin=https://147.182.147.133

So the Gateway is up, but it’s refusing the browser WS handshake because you’re opening the UI from a remote origin (your Mac hitting the VPS IP).

You’ve got two sane fixes:

Option A (recommended): SSH tunnel, keep origin “local”

From your Mac:

ssh -N -L 18789:127.0.0.1:18789 openclaw@147.182.147.133

Then open:

#

This avoids punching web access wide open and usually avoids the origin headache entirely.

Option B: explicitly allow your UI origin

If you want to open the UI at https://147.182.147.133 (as your log shows), add that exact origin to config:

openclaw config set gateway.controlUi.allowedOrigins '["https://147.182.147.133"]' --strict-json
sudo systemctl restart openclaw.service

Notes:

  • The value must be full origins (scheme + host + optional port). If you access it as http://...:18789, you must allow http://147.182.147.133:18789 instead.
  • Avoid the “dangerous” fallback knobs (gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback) unless you really know why you need them.

Docs: https://docs.openclaw.ai/web/control-ui (see the allowedOrigins section)

About the “embedded run … unknown error”

#

That’s usually just fallout from the Control UI connection being rejected. Fix the origin issue first; if it persists after you can actually connect, grab the next few lines around that error from openclaw logs --follow / journal and we’ll chase it.

frail sluice
#

I get "An unknown error occurred" message back from every mesasge i send my bot

dim sparrowBOT
#

That “An unknown error occurred” is OpenClaw’s generic run failed message. The only way to know why is to look at the gateway logs for the exact failure right when you send a message.

Given your earlier logs showed:

  • FailoverError: Unknown model: google-gemini-cli/gemini-3-1-pro-preview

…my bet is the agent is still trying to run on a model ref that no longer resolves, so every inbound message triggers an agent run → fails immediately → you get the generic error.

Do this (on the VPS) and paste the output

1) Confirm the gateway is actually healthy

openclaw gateway status
openclaw status

2) Check model resolution (this is the common “everything errors” cause)

#
openclaw models status
openclaw models list

If models status still shows google-gemini-cli/gemini-3-1-pro-preview (or anything “Unknown model”), set the default to something that exists in models list:

openclaw models set <provider/model-from-models-list>
sudo systemctl restart openclaw.service

3) Capture the real error from logs while reproducing

In one SSH window:

sudo journalctl -u openclaw.service -f

Then send a message to the bot, and copy/paste the new log lines that appear.