#my vps don't start because i connected openclaw to openrouter api

1 messages · Page 1 of 1 (latest)

keen compass
#

Hello! I'm continuing a troubleshooting session from earlier with another assistant. Here is a quick summary of what we did to fix my Gateway, and the new minor issue I just ran into.

What we fixed:

  1. I had the plugin not found error due to an ownership mismatch. We removed it from the config.
  2. I then hit the Cannot access 'ANTHROPIC_MODEL_ALIASES' before initialization startup crash (the known bug in OpenClaw 2026.3.12).
  3. We successfully downgraded and pinned OpenClaw to 2026.3.11. Since I'm using Hostinger, we went with a custom Dockerfile to keep the Hostinger wrapper. We pinned it via digest and built a local image named hvps-openclaw-pinned:2026.3.11. Everything was running perfectly!

My current issue:
I tried to add my OPENROUTER_API_KEY using the Hostinger Web Panel interface. The panel successfully added the key to my .env file, but then its automated deploy script crashed with this error:
pull access denied for hvps-openclaw-pinned, repository does not exist or may require 'docker login'

Because of this crash, the deployment aborted and right now my server is completely down and won't restart.

My questions for you:

  1. I assume Hostinger's script is hardcoded to run a docker pull before starting, which fails because our pinned image is local. Since the .env file is already updated, can I just jump into my SSH terminal, go to /docker/openclaw-bfch/ and run docker compose up -d to get the server back online?
  2. Does this mean I should stop using the Hostinger web panel to manage env vars and restarts from now on, and only do it via SSH?

Thanks for picking this up!

wanton hazelBOT
#

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

glossy onyxBOT
#
  1. Yes — that’s the right recovery move as long as the pinned image still exists locally on the VPS.

From SSH:

cd /docker/openclaw-bfch

# sanity check: does the local image exist?
docker image ls | grep hvps-openclaw-pinned || true

# bring it back up WITHOUT trying to pull
docker compose up -d --pull never

docker compose ps
docker compose logs -f --tail=200
#

Notes:

  • docker compose up -d will normally not pull if the image is already present, but adding --pull never makes it explicit (and avoids repeating the Hostinger “pull” failure).
  • If docker image ls shows no hvps-openclaw-pinned:2026.3.11, you’ll need to rebuild it on the VPS (same Dockerfile you used before), then docker compose up -d again.
  1. Practically: yes, avoid the Hostinger panel “deploy/restart” workflow when you’re using a local-only image name.

What’s happening is very common with VPS panels: they try to do a docker pull (or docker compose pull) as part of every deploy. That can never work for an image that only exists locally (like hvps-openclaw-pinned:2026.3.11).

If you want to keep using the panel reliably, you have two options:

  • Push the image to a registry (Docker Hub / GHCR / etc.) and reference it by a real repo name, so pulls succeed.
  • Or change the setup so the panel does a build from your Dockerfile instead of pulling (only works if Hostinger supports that flow).

If you paste:

  • docker compose ps
  • and the last ~80 lines of docker compose logs --tail=80

…I can tell you quickly whether it’s just the pull issue or if OpenClaw is failing to boot for a second reason. (Don’t paste any API keys.)

keen compass
#

Everything is running perfectly and the server is stable!

However, I have a quick configuration question. When I type /model in the OpenClaw UI, I don't see any of the OpenRouter models listed.

I looked into my openclaw.json config file, and I noticed that the agents.defaults.models list only contains hardcoded entries for OpenAI, Anthropic, and Google. It looks like this:

  agents: {
    defaults: {
      model: {
        primary: 'openai/gpt-5.4',
      },
      models: {
        'openai/gpt-5.4': {
          alias: 'ChatGPT 5.4',
        },
        // ... only openai, anthropic and google models here ...
      },
glossy onyxBOT
#

That’s expected with your current config.

Why you don’t see OpenRouter in /model

/model isn’t a live “show me everything OpenRouter has” browser. It shows the allowed model catalog from:

  • agents.defaults.models

So if that map only contains OpenAI/Anthropic/Google entries, the picker will only show those — even if OPENROUTER_API_KEY is set.

Docs: https://docs.openclaw.ai/concepts/models (see “Model is not allowed” + allowlist behavior)


Fix: add (a few) OpenRouter models to agents.defaults.models

Minimal example (JSON5):

#
agents: {
  defaults: {
    model: {
      primary: "openai/gpt-5.4", // keep your current default if you want
    },
    models: {
      "openai/gpt-5.4": { alias: "GPT 5.4 (direct)" },

      // add OpenRouter models you want to appear in /model:
      "openrouter/anthropic/claude-sonnet-4-5": { alias: "Sonnet (OpenRouter)" },
      "openrouter/moonshotai/kimi-k2": { alias: "Kimi K2 (OpenRouter)" },
    },
  },
}
#

After the gateway reloads/restarts, those should show up in /model.

Docs on OpenRouter provider: https://docs.openclaw.ai/providers/openrouter


One more gotcha (since you’re in Docker)

Make sure OPENROUTER_API_KEY is actually getting into the container (via env_file: or environment: in docker-compose.yml). Editing a host .env file only helps if Compose is configured to pass it through.

Quick check (run wherever the openclaw CLI is available, usually inside the container):
openclaw models status → it should not show OpenRouter as “Missing auth”.

If you paste your docker-compose.yml with secrets removed, I can point out exactly where to add OPENROUTER_API_KEY if it’s not being passed through.

keen compass
#

The model configuration worked perfectly, thank you so much! I can see my custom OpenRouter list now.

Since I still have you here, I'd like to ask about an issue I'm having with the WhatsApp channel.

When I go to the channels UI, it shows WhatsApp as Configured (Yes) and Linked (Yes), but Running and Connected are both "No". It says my number is already linked (Auth age 11h), but it throws this red error block:

{"error":{"data":{"reason":"401","location":"odn"},"isBoom":true,"isServer":false,"output":{"statusCode":401,"payload":{"statusCode":401,"error":"Unauthorized","message":"Connection Failure"},"headers":{}}},"date":"2026-03-14T21:54:15.338Z"}

How can I clear this 401 error and properly get it connected?

Also, a more general question: is there a way to receive WhatsApp notifications when the bot talks to me, without having to buy a secondary/dedicated phone number just for the bot?

latent agate
#

i was struggling with the same issue, ended up using useclawy.com and it just worked in like 60 seconds lol

glossy onyxBOT
#

That 401 Unauthorized from the WhatsApp web socket almost always means the linked WhatsApp-Web session was revoked / is no longer accepted by WhatsApp, even though you still have a creds.json on disk (so the UI says “Linked: Yes”).

Fix: hard reset the WhatsApp link and re-scan QR

  1. On your phone: WhatsApp → Settings → Linked devices
    Remove anything that looks like your VPS/OpenClaw session (or “log out of all devices” if you’re fine with that).

  2. On the gateway host (inside the container if that’s where openclaw runs):

openclaw channels logout --channel whatsapp
openclaw channels login --channel whatsapp

That forces a fresh QR + new creds.

  1. Then verify:
openclaw channels status --probe
#
openclaw logs --follow

If it immediately falls back into 401 again, the next two things to check are:

  • You don’t have two OpenClaw instances/containers trying to use the same WhatsApp account (that can cause sessions to get kicked).
  • Your container’s WhatsApp creds path is on a persistent volume (so you’re not half-restoring stale auth state on restart). Docs note the path as: ~/.openclaw/credentials/whatsapp/<accountId>/creds.json.

Docs: https://docs.openclaw.ai/channels/whatsapp (see Logout behavior + relink flow)
and https://docs.openclaw.ai/channels/troubleshooting


About WhatsApp notifications without a dedicated number

If the bot runs on your personal number, the bot is effectively “you” on WhatsApp — so it can’t really “notify you” as a separate sender in the normal way. The best you can do is the self-chat pattern (supported via selfChatMode), but:

  • messages will look like they’re from you,
  • and many people don’t get meaningful “incoming” notifications for their own outgoing messages.
#

So for true WhatsApp-style “the bot pings me” notifications, a separate WhatsApp identity/number is the clean solution (even an inexpensive eSIM).

If you want a no-extra-number workaround, the usual pattern is:

  • keep WhatsApp for chatting with the bot, but
  • have it send notifications to you on another surface (Telegram/Discord/Signal), where it can be a separate sender.

If you paste (redacting secrets) the output of openclaw channels status --probe + the first WhatsApp-related error lines from openclaw logs --follow, I can tell if this is a simple relink or a “two instances fighting” situation.

#

Good to know it worked for you.

Just a heads-up for anyone reading: useclawy.com isn’t an official OpenClaw install path, so treat it like any third‑party host/wrapper:

  • assume you’re trusting them with your gateway state (sessions, creds, channel tokens) unless they clearly document otherwise
  • don’t paste API keys / WhatsApp creds into anything you don’t fully trust
  • if something breaks there, the right support channel is their support (we can’t really debug a managed installer we don’t control)

For the “official” self-host route, these are the reference docs:

If you’re up for it, what was the key difference that made it “just work” (provider, docker image, UI wizard, etc.)? That kind of detail helps others choose the right path.

keen compass
#

I followed your steps! I successfully logged out, generated a new QR code, and scanned it. The console even said âś… Linked after restart; web session ready.

However, it immediately fell back into the 401 loop right after.

Regarding your two theories:

  1. My creds path is on a persistent volume (my docker-compose uses ./data:/data and volumes: is properly set).
  2. I shouldn't have any other OpenClaw instances running, unless there's a ghost container I'm unaware of.

Here is the sanitized output. I also noticed a weird Could not auto-approve pending device warning at the very end.

docker exec openclaw-bfch-openclaw-1 openclaw channels status --probe
Checking channel status (probe)…
Gateway reachable.

  • WhatsApp default: enabled, configured, not linked, stopped, disconnected, dm:pairing, error:{"error":{"data":{"reason":"401","location":"odn"},"isBoom":true,"isServer":false,"output":{"statusCode":401,"payload":{"statusCode":401,"error":"Unauthorized","message":"Connection Failure"},"headers":{}}},"date":"..."}

docker compose logs --tail=50
openclaw-1 | [whatsapp] [default] starting provider ([MY REDACTED NUMBER])
openclaw-1 | [ws] webchat connected conn=...
openclaw-1 | WhatsApp session logged out. Run: openclaw channels login
openclaw-1 | [whatsapp] [default] channel exited: {"error":{"data":{"reason":"401","location":"frc"}...
openclaw-1 | [whatsapp] [default] auto-restart attempt 1/10 in 5s
openclaw-1 | [whatsapp] [default] starting provider ([MY REDACTED NUMBER])
openclaw-1 | WhatsApp session logged out. Run: openclaw channels login
openclaw-1 | [whatsapp] [default] channel exited: {"error":{"data":{"reason":"401","location":"lla"}...
// ... loop continues ...
openclaw-1 | [WARN] Could not auto-approve pending device after all attempts

Since the persistent volume is correct, what should I check next to stop it from immediately revoking the session? Could that auto-approve warning be related?

glossy onyxBOT
#

That log is the smoking gun:

  • WhatsApp session logged out. Run: openclaw channels login
  • followed by 401 with Baileys-style location codes like frc/lla/odn

At this point it’s not your volume or “ghost container” in the usual sense — it’s the WhatsApp Web library (Baileys) getting a server-side “device_removed / unauthorized” during the auth handshake, so OpenClaw immediately marks the session as logged out and loops.

Most likely root cause (known Baileys regression)

There’s a known upstream Baileys breakage that produces exactly this symptom: infinite 401 Unauthorized reconnect loop with those location codes. OpenClaw tracked it here:

https://github.com/openclaw/openclaw/issues/19907

So the “next thing to check” is: which Baileys version your pinned OpenClaw image contains.

Run this inside the container:

#
docker exec openclaw-bfch-openclaw-1 openclaw --version
docker exec openclaw-bfch-openclaw-1 node -p "require('@whiskeysockets/baileys/package.json').version"

If it shows Baileys 7.0.0-rc.9 (or another known-broken build), the fix is not more relinking — it’s:

Fix options

Option A (recommended): upgrade OpenClaw to a build that includes the Baileys fix.
You already avoided 2026.3.12 due to that Anthropic crash — but you should be able to move forward to a newer version (post-2026.3.12) once that crash is fixed, and get WhatsApp working again.

Option B (temporary, Docker-only): bake the Baileys patch into your custom Dockerfile (so it survives rebuilds). That issue includes the exact changes people used to unbreak the handshake. I’d only do this if upgrading OpenClaw isn’t possible for you right now.

About Could not auto-approve pending device…

That warning is almost certainly unrelated to WhatsApp. It’s about OpenClaw device/node pairing auto-approval (a node or UI tried to pair and couldn’t be silently approved). It won’t cause a WhatsApp 401 loop.


#

If you paste the two version outputs (openclaw --version + the Baileys version), I can tell you immediately whether you’re hitting that exact regression and which of the two fix paths is the least painful with your Hostinger+pinned-image setup.

keen compass
#

Here are the outputs from the container:

openclaw --version
OpenClaw 2026.3.11 (29dc654)

node -p "require('@whiskeysockets/baileys/package.json').version"
Error: Cannot find module '@whiskeysockets/baileys/package.json'
code: 'MODULE_NOT_FOUND'

Since we pinned this by building a custom image with RUN npm i -g openclaw@2026.3.11, I assume the baileys package isn't directly resolvable from the default /data working directory, but is instead tucked away in the global node_modules path.

However, given that we are definitively running OpenClaw 2026.3.11, do you know if this specific version contains the broken Baileys build that causes the 401 loop?

If it does, what is the best way to patch it directly in my custom Dockerfile since I'm trying to avoid version 2026.3.12 (because of the Anthropic crash)?

glossy onyxBOT
#

Yep — OpenClaw 2026.3.11 ships with the broken Baileys build.

You can verify it without guessing:

npm view openclaw@2026.3.11 dependencies --json | jq -r '."@whiskeysockets/baileys"'
# -> 7.0.0-rc.9

…and that 7.0.0-rc.9 is exactly the one that’s known to produce the 401 Unauthorized reconnect loop with locations like frc/lla/odn (the symptom you’re seeing).


Why your require('@whiskeysockets/baileys/…') failed

Node doesn’t resolve global installs from an arbitrary working directory. In a container where you did npm i -g openclaw@2026.3.11, Baileys lives under:

#
$(npm root -g)/openclaw/node_modules/@whiskeysockets/baileys

Quick check:

docker exec openclaw-bfch-openclaw-1 sh -lc '
  GLOBAL="$(npm root -g)";
  node -p "require(\"$GLOBAL/openclaw/node_modules/@whiskeysockets/baileys/package.json\").version"
'

Best way to patch it in your custom Dockerfile (recommended approach)

Since you’re already building a custom image, patch Baileys at build time right after installing OpenClaw.

#

Add a RUN block like this after your npm i -g openclaw@2026.3.11:

RUN set -eux; \
  GLOBAL="$(npm root -g)"; \
  BAILEYS="$GLOBAL/openclaw/node_modules/@whiskeysockets/baileys/lib"; \
  test -d "$BAILEYS"; \
  \
  # backups (optional but nice)
  cp "$BAILEYS/Utils/validate-connection.js" "$BAILEYS/Utils/validate-connection.js.orig"; \
  cp "$BAILEYS/Socket/socket.js" "$BAILEYS/Socket/socket.js.orig"; \
  \
  # Patch 1: passive true -> false
  sed -i 's/passive: true,/passive: false,/g' "$BAILEYS/Utils/validate-connection.js"; \
  \
  # Patch 2: remove lidDbMigrated
#
  sed -i '/lidDbMigrated: false/d' "$BAILEYS/Utils/validate-connection.js"; \
  \
  # Patch 3: noise.finishInit timing
  sed -i 's/await noise\\.finishInit();/noise.finishInit();/g' "$BAILEYS/Socket/socket.js"; \
  \
  # sanity checks (fail build if patch didn't apply)
  grep -n "passive: false" "$BAILEYS/Utils/validate-connection.js" | head; \
  ! grep -n "lidDbMigrated" "$BAILEYS/Utils/validate-connection.js"; \
  grep -n "noise.finishInit();" "$BAILEYS/Socket/socket.js" | head

After you rebuild + redeploy that image, do one clean relink:

openclaw channels logout --channel whatsapp