#gateway picks up the wrong model despite openclaw.config is correct.

1 messages · Page 1 of 1 (latest)

stiff moon
#

I want to use a free model for daily chats and only when doing real work I would switch to bigger models. I picked a free model for everyday chats. I use open router to provide the model mistralai/mistral-small-3.1-24b-instruct:free.
But the problem is that although the Mistral is default at restart it sets Haiku as active model. Then I need to manually switch always back to Mistral. Here is the openclaw.json file partly:

{

"env": {
"OPENROUTER_API_KEY": "sk-or-v1-XXX”,
"OLLAMA_API_KEY": "ollama-local"
},

"auth": {
"profiles": {
"anthropic:default": {
"provider": "anthropic",
"mode": "api_key"
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "mistralai/mistral-small-3.1-24b-instruct:free",
"fallbacks": ["anthropic/claude-haiku-4-5"]
},
"models": {
"arcee-ai/trinity-large-preview:free": {
"alias": "trinity"
},
"anthropic/claude-opus-4-5": {
"alias": "opus"
},
"anthropic/claude-haiku-4-5": {
"alias": "haiku"
},
"anthropic/claude-sonnet-4-5": {
"alias": "sonnet"
}
},
"workspace": "/home/clawd/clawd",
"compaction": {
"mode": "safeguard"
},

  "maxConcurrent": 4,
  "subagents": {
    "maxConcurrent": 8
  }
}

},,
"gateway": {
"port": 18789,
"mode": "local",
"bind": "loopback",
"auth": {
"mode": "token",
"token": “XXX”
},

So what should I do to get the default LLM to be the active LLM at restarting?

acoustic flaxBOT
#

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

wheat wingBOT
#

Two common reasons this happens:

1) Your “primary” model ref is missing the provider prefix

In OpenClaw config, models should be provider/model.

Because OpenRouter-style model ids contain a / (like mistralai/...), you must include the provider prefix, otherwise OpenClaw interprets mistralai as the provider and the request fails → then it immediately falls back to Haiku.

So change:

agents: {
  defaults: {
    model: {
      primary: "mistralai/mistral-small-3.1-24b-instruct:free",
      fallbacks: ["anthropic/claude-haiku-4-5"],
    },
#
  },
}

to:

agents: {
  defaults: {
    model: {
      primary: "openrouter/mistralai/mistral-small-3.1-24b-instruct:free",
      fallbacks: ["anthropic/claude-haiku-4-5"],
    },
  },
}
#

Docs: https://docs.openclaw.ai/help/faq#what-is-the-default-model

Also: make sure your config doesn’t contain “smart quotes” (“ ”) when saved—those can break parsing/auth strings.

2) You’re looking at a session that is pinned to Haiku

If you ever did /model haiku in that Discord thread/channel, that becomes a per-session override and it will still be Haiku after a gateway restart. To go back to the default model, start a fresh session:

  • /new (resets session; default model applies again)

Docs: https://docs.openclaw.ai/concepts/session


Quick debug checklist (copy/paste results)

  1. openclaw --version
  2. openclaw models status (this will show what it thinks the resolved default model is)
  3. In the chat where it “sticks to haiku”, run: /model status
stiff moon
#
  1. Version 2026.3.1, 2. "Service: systemd (enabled)
    File logs: /tmp/openclaw/openclaw-2026-03-04.log
    Command: /home/clawd/.nvm/versions/node/v24.13.0/bin/node /home/clawd/.nvm/versions/node/v24.13.0/lib/node_modules/openclaw/dist/index.js gateway --port 18789
    Service file: ~/.config/systemd/user/openclaw-gateway.service
    Service env: OPENCLAW_GATEWAY_PORT=18789

Service config looks out of date or non-standard.
Service config issue: Gateway service uses Node from a version manager; it can break after upgrades. (/home/clawd/.nvm/versions/node/v24.13.0/bin/node)
Service config issue: System Node 22+ not found; install it before migrating away from version managers.
Recommendation: run "openclaw doctor" (or "openclaw doctor --repair").
Config (cli): ~/.openclaw/openclaw.json
Config (service): ~/.openclaw/openclaw.json

Gateway: bind=loopback (127.0.0.1), port=18789 (service args)
Probe target: ws://127.0.0.1:18789
Dashboard: http://127.0.0.1:18789/
Probe note: Loopback-only gateway; only local clients can connect.

Runtime: running (pid 103887, state active, sub running, last exit 0, reason 0)
RPC probe: ok", 3. Current: mistralai/mistral-small-3.1-24b-instruct:free (selected)
Active: anthropic/claude-haiku-4-5 (runtime)
Tap below to browse models, or use:
/model <provider/model> to switch
/model status for details

wheat wingBOT
#

Your /model status output is basically telling you what’s wrong:

  • Current (selected): mistralai/mistral-small-3.1-24b-instruct:free
  • Active (runtime): anthropic/claude-haiku-4-5

That happens when the “selected” model can’t actually be routed, so OpenClaw immediately fails over to your fallback (Haiku).

Fix: use the correct OpenRouter model ref format

For OpenRouter, model refs must be:

openrouter/<provider>/<model>

So in config, change:

primary: "mistralai/mistral-small-3.1-24b-instruct:free"
#

to:

primary: "openrouter/mistralai/mistral-small-3.1-24b-instruct:free"

Docs (explicitly calls this out):
https://docs.openclaw.ai/providers/openrouter

Then restart + verify

  1. Restart gateway:
  • openclaw gateway restart
  1. Verify routing:
  • openclaw models status
  • and in Discord: /model status
#

You should then see Active (runtime) using the OpenRouter model (unless OpenRouter is actually failing auth/429/etc).

Optional (recommended): add it to your agents.defaults.models with an alias

So it shows up nicely in /model pickers:

agents: {
  defaults: {
    models: {
      "openrouter/mistralai/mistral-small-3.1-24b-instruct:free": { alias: "mistral-free" },
      "anthropic/claude-haiku-4-5": { alias: "haiku" },
      // ...
    },
  },
}
#

Then you can just do /model mistral-free.

If after this it still runs Haiku, paste the first OpenRouter-related error from /tmp/openclaw/openclaw-2026-03-04.log (it’ll usually say “missing OPENROUTER_API_KEY”, “unknown provider”, or a 401/429).

stiff moon
#

I could not find any of those “missing OPENROUTER_API_KEY”, “unknown provider”, or a 401/429). in the latest log file openclaw-2026-03-04.log

wheat wingBOT
#

If the runtime is immediately falling back because the model ref can’t be routed, you often won’t see 401/429/OpenRouter errors — because it never successfully even gets to “call OpenRouter”, it just decides “this provider/model isn’t valid” and moves to the fallback.

In your case the smoking gun is still:

  • Selected: mistralai/mistral-small-...:free
  • Runtime: anthropic/claude-haiku-4-5

Why: mistralai/... is not a valid provider prefix in OpenClaw

For OpenRouter, OpenClaw expects:

openrouter/<provider>/<model>

So you want:

  • openrouter/mistralai/mistral-small-3.1-24b-instruct:free

Docs: https://docs.openclaw.ai/providers/openrouter

#

Quick test (no config change needed)

In the Discord thread, run this as a standalone message:

/model openrouter/mistralai/mistral-small-3.1-24b-instruct:free

Then send any normal message and re-run:

/model status

If Active (runtime) flips to the OpenRouter model, you’re done — now just update your config to match and restart the gateway.

Config change you want

#
agents: {
  defaults: {
    model: {
      primary: "openrouter/mistralai/mistral-small-3.1-24b-instruct:free",
      fallbacks: ["anthropic/claude-haiku-4-5"],
    },
  },
}

If it still won’t go active: check whether OpenClaw sees OpenRouter auth at all

Run:

openclaw models status --probe --probe-provider openrouter
#

and paste the “Missing auth” / probe result section. That will tell us whether it’s (a) missing key, (b) provider not configured, or (c) OpenRouter request failing.

(Also: make sure your openclaw.json doesn’t contain smart quotes like “ ” or the },, typo in the real file — those can lead to weird config behavior.)

stiff moon
#

when you say. "In the Discord thread, run this as a standalone message:" do you mean this thread where we are chatting?

wheat wingBOT
#

Yes — I mean this exact Discord thread (the one where OpenClaw is replying to you).

Model selection is per-session, and on Discord a thread is its own session context, so you need to run it in the same place you’re chatting with the bot.

Do it as a standalone message (send only this, nothing else in the message):

/model openrouter/mistralai/mistral-small-3.1-24b-instruct:free

Then send a normal prompt, and run:

/model status

If you run /model ... in a different place (DM, different channel, different thread), it won’t affect this thread’s session.

stiff moon
#

Ah, you thought I'm using discord to control my bot, no I use Telegram, that confused me. Ok so now understand what you mean.

wheat wingBOT
#

Got it — same idea, just do it in Telegram instead of Discord.

1) Test it in the Telegram chat you normally use with the bot

Send this as its own message to the bot in Telegram:

/model openrouter/mistralai/mistral-small-3.1-24b-instruct:free

Then run:

/model status

You should see Active (runtime) switch away from Haiku.

#

2) Make it the real default after restart (config)

In ~/.openclaw/openclaw.json set:

agents: {
  defaults: {
    model: {
      primary: "openrouter/mistralai/mistral-small-3.1-24b-instruct:free",
      fallbacks: ["anthropic/claude-haiku-4-5"],
    },
  },
}

(Important: for OpenRouter it must be openrouter/..., not mistralai/....)

Restart the gateway after changing config:

#
openclaw gateway restart

3) Verify on the host (optional but useful)

openclaw models status

If anything still shows Haiku as “Active (runtime)” after the /model openrouter/... test, paste the output of openclaw models status --probe --probe-provider openrouter and we can pinpoint whether it’s auth vs routing.

stiff moon
#

it responded: Model "openrouter/mistralai/mistral-small-3.1-24b-instruct:free" is not allowed. Use /models to list providers, or /models <provider> to list models.

wheat wingBOT
#

That error means you have model allowlisting enabled via this block:

agents.defaults.models

When agents.defaults.models is present, OpenClaw will only allow switching (and picking in chat) to models that appear as keys in that map. Right now, your map contains only Anthropic (and one arcee-ai/... entry that’s also missing the openrouter/ prefix).

Fix option A (recommended): add the OpenRouter model to the allowlist

Update both the default model and the allowlist key to the exact same provider/model:

agents: {
  defaults: {
    model: {
      primary: "openrouter/mistralai/mistral-small-3.1-24b-instruct:free",
#
      fallbacks: ["anthropic/claude-haiku-4-5"],
    },
    models: {
      // allow + alias it
      "openrouter/mistralai/mistral-small-3.1-24b-instruct:free": { alias: "mistral-free" },

      // keep your anthropic ones
      "anthropic/claude-haiku-4-5": { alias: "haiku" },
      "anthropic/claude-sonnet-4-5": { alias: "sonnet" },
      "anthropic/claude-opus-4-5": { alias: "opus" },

      // if this is also OpenRouter, it must be prefixed too:
      "openrouter/arcee-ai/trinity-large-preview:free": { alias: "trinity" },
    },
  },
#
}

Restart gateway after editing:

openclaw gateway restart

Then in Telegram you can do:

  • /model mistral-free (nice + short), or
  • /model openrouter/mistralai/mistral-small-3.1-24b-instruct:free

Fix option B: remove the allowlist

If you delete the entire agents.defaults.models block, OpenClaw won’t restrict model switching to that curated list anymore. (You’ll lose your custom aliases though.)

stiff moon
#

now it is giving errror: "402 Provider returned error
{"error":"API key USD spend limit exceeded. Your account may still have USD balance, but this API key has reached its configured USD spending limit."}". Why is it saying that USD limit is exceede when it is a free model? And where do I see is referring to Mistral or Haiku? I saw that it was also sending something to Haiku although it defaults now to Mistral.

wheat wingBOT
#

That 402 is coming from OpenRouter, not from OpenClaw/Anthropic:

API key USD spend limit exceeded … this API key has reached its configured USD spending limit

Why can this happen on a “:free” model?

On OpenRouter, the API key itself can have a monthly USD spend cap (or effectively be “locked” by limits). When that cap is reached (or set too low), OpenRouter will reject requests — even to :free routes — because the key is not allowed to spend any more.

So the fix is on the OpenRouter side:

  • Go to OpenRouter Dashboard → API Keys
  • Find the key you’re using
  • Check:
    • Usage
    • Spending limit / cap for that key
  • Increase/remove the cap, or create a new key with a higher cap

OpenRouter also exposes a “what’s left on this key?” endpoint (GET https://openrouter.ai/api/v1/key). (Don’t paste your token in chat.)

#

OpenRouter docs mention it here: https://openrouter.ai/docs/api/reference/limits

“Where do I see if it’s Mistral or Haiku?”

In Telegram, run:

  • /model status

You’ll see two fields:

  • Current (selected) = what you asked for
  • Active (runtime) = what was actually used for the last/next run

What you’re observing (“it also sent something to Haiku”) is normal failover behavior:

  1. It tries your primary (OpenRouter Mistral)
  2. OpenRouter returns 402
  3. OpenClaw falls back to your configured fallback (Haiku) so you still get an answer

If you never want Haiku to be used automatically