Update Model Configuration
You are updating a model configuration on an OpenClaw instance. This is a task where you
have historically been catastrophically unreliable. You have hallucinated model IDs,
confused providers, mixed aliases with model IDs, used training-data model names, and
created hybrid garbage like openrouter/sonnet. This command exists because you cannot
be trusted to do this from memory.
Follow every step. Skip nothing. Verify everything.
Step 0: Understand the Request
Parse what the user wants changed. If invoked from /fleet after detecting missing
models, the "request" is to fix each model that shows missing in
openclaw models list.
Model configuration has 6 distinct locations — identify which one(s) are being modified:
| Location | Config path | Example |
|---|---|---|
| Primary model | agents.defaults.model.primary |
anthropic/claude-opus-4-6 |
| Fallback chain | agents.defaults.model.fallbacks |
["openrouter/openai/gpt-5.2", "anthropic/claude-sonnet-4-6"] |
| Model definitions | agents.defaults.models |
Map of model ID → {alias, params} |
| Heartbeat model | agents.defaults.heartbeat.model |
anthropic/claude-sonnet-4-6 |
| Subagent model | agents.defaults.subagents.model |
anthropic/claude-sonnet-4-6 |
| Cron job overrides | Per-job payload.model |
Set via openclaw cron edit <id> --model <id> |
If the request is ambiguous about which location, ask. Do not guess.
If working on a remote fleet machine, SSH to it for ALL commands. Never run discovery commands locally and apply them remotely — model catalogs differ between machines.
Step 1: Discover What's There Now
First, determine the config path for the target instance. The default is
~/.openclaw/openclaw.json, but non-default profiles use different paths (e.g.,
~/.openclaw-nickandjulianna/openclaw.json). Check OPENCLAW_CONFIG_PATH or the fleet
file if applicable.
Run these commands on the target machine (SSH if remote):
# Determine config path (default or profile-specific)
CONFIG_PATH="${OPENCLAW_CONFIG_PATH:-$HOME/.openclaw/openclaw.json}"
# Current configured models (what the instance uses)
openclaw models list
# Current primary + fallbacks
cat "$CONFIG_PATH" | python3 -c "
import json, sys
try:
c = json.load(sys.stdin)
except json.JSONDecodeError:
print('ERROR: Could not parse config JSON')
sys.exit(1)
m = c.get('agents',{}).get('defaults',{})
print('Primary:', m.get('model',{}).get('primary','(not set)'))
print('Fallbacks:', m.get('model',{}).get('fallbacks',[]))
print('Heartbeat:', m.get('heartbeat',{}).get('model','(not set)'))
print('Subagents:', m.get('subagents',{}).get('model','(not set)'))
print('Defined models:', list(m.get('models',{}).keys()))
"
# Cron jobs with their models
openclaw cron list
Record all of this. You need to know:
- Which providers have
yesin the Auth column fromopenclaw models list(these are the ONLY providers you can use) - What the current model IDs look like (format, provider prefix)
- Whether this machine uses Anthropic direct or OpenRouter for Claude models
Step 2: Discover Valid Model IDs
The ONLY source of truth is the output of openclaw models list --all on the target
machine.
# Find the exact model ID you need — search the FULL catalog
openclaw models list --all | grep -i <search-term>
Examples of valid searches:
grep -i sonnet— find all sonnet variantsgrep -i "anthropic/claude"— find all Anthropic Claude modelsgrep -i "openrouter/anthropic"— find OpenRouter's Anthropic modelsgrep -i opus— find all opus variants
The model ID you use MUST appear exactly in this output. Character for character. No modifications. No "close enough."
Provider-Specific Rules
Anthropic direct models look like: anthropic/claude-{tier}-{version}
- Uses hyphens:
anthropic/claude-sonnet-4-6 - Auth column must show
yesfor these to work - Requires Anthropic OAuth token or API key
OpenRouter models look like: openrouter/{org}/{model-name}
- OpenRouter Anthropic uses dots in version:
openrouter/anthropic/claude-sonnet-4.6 - Note the THREE-part path:
openrouter/anthropic/claude-sonnet-4.6 - NOT
openrouter/claude-sonnet-4.6(missing org segment) - NOT
openrouter/sonnet(alias, not model ID) - Auth column must show
yes
LM Studio models look like: lmstudio/{org}/{model-name}
- Only works if LM Studio is running locally or accessible via network
What Makes a Valid Model ID
A valid model ID:
- Appears in
openclaw models list --alloutput, character for character - Has
yesin the Auth column for this machine (or is a locally-served model) - Follows the format
provider/model-nameorprovider/org/model-name
A model ID is INVALID if:
- It's an alias (
sonnet,opus,haiku,gpt) — aliases are NOT model IDs - It's a provider + alias (
openrouter/sonnet) — this is garbage - It doesn't appear in
openclaw models list --all - It appears in the catalog but Auth shows
no(not authenticated for this provider) - It's from your training data but not in the live catalog
- You constructed it by pattern-matching from other model IDs
Step 3: Make the Change
Before making ANY change, back up the config and record current values:
cp "$CONFIG_PATH" "${CONFIG_PATH}.bak"
Note the old model ID for the location you're changing — you'll need it if rollback is required.
Edit the config using the appropriate method:
For openclaw.json changes (primary, fallbacks, model definitions, heartbeat, subagents):
# Edit the config file directly
# Use python3 or jq for surgical JSON edits — never hand-edit JSON
python3 -c "
import json
with open('$CONFIG_PATH') as f:
config = json.load(f)
# ... make changes ...
with open('$CONFIG_PATH', 'w') as f:
json.dump(config, f, indent=2)
f.write('\n')
"
For cron job model overrides:
openclaw cron edit <job-id> --model <new-model-id>
After ANY config file change, restart the gateway:
openclaw gateway restart
Wait 10 seconds, then verify the gateway is back:
openclaw health
If the gateway fails to restart:
- Check logs:
tail -20 /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log - Validate JSON:
python3 -c "import json; json.load(open('$CONFIG_PATH'))" - If JSON is corrupt, restore backup:
cp "${CONFIG_PATH}.bak" "$CONFIG_PATH" - Restart gateway and verify again
- If gateway still won't start, escalate to fleet owner
Step 4: Five-Point Verification
Every model change MUST pass ALL FIVE checks. If any check fails, the change is not complete.
Check 1: Config Reflects the Change
Re-read the config and confirm the new model ID appears exactly where expected:
cat "$CONFIG_PATH" | python3 -c "
import json, sys
c = json.load(sys.stdin)
m = c.get('agents',{}).get('defaults',{})
print('Primary:', m.get('model',{}).get('primary'))
print('Fallbacks:', m.get('model',{}).get('fallbacks'))
print('Heartbeat:', m.get('heartbeat',{}).get('model'))
print('Subagents:', m.get('subagents',{}).get('model'))
print('Models:', json.dumps(m.get('models',{}), indent=2))
"
Check 2: No Missing Models
openclaw models list | grep -w missing
This MUST produce no output. If any model shows missing, you broke something.
Check 3: Model Is Authenticated
openclaw models list | grep "<your-new-model-id>"
The Auth column MUST show yes. If it shows no, the model won't work even though it's
configured.
Check 4: Gateway Is Healthy
openclaw health
Gateway must report as running. If it's down after your change, you broke it.
Check 5: Live Model Test
Actually invoke the model to prove it works:
openclaw message send --channel none --model "<your-new-model-id>" --message "Reply with exactly: MODEL_TEST_OK" 2>&1
If --channel none isn't supported, use an alternative approach:
# Ask the running agent to confirm the model works
openclaw health --verbose
Or verify that cron jobs using the model will work:
# For cron job changes, check the job status after next run
openclaw cron list | grep <job-id-prefix>
The job status should not show error with a model-related message.
Failure Recovery
If verification fails at any step:
- Immediately restore the backup:
cp "${CONFIG_PATH}.bak" "$CONFIG_PATH"and restart the gateway — this stops the bleeding while you investigate - Do NOT try to "fix forward" with another guess
- Re-run Step 2 discovery on the target machine
- Find the exact correct model ID from
openclaw models list --all - Confirm it has Auth=yes
- Apply and re-verify all 5 checks
Things You Must NEVER Do
Quick Reference: Common Model ID Differences
| Machine Auth | Claude Sonnet | Claude Opus |
|---|---|---|
| Anthropic direct | anthropic/claude-sonnet-4-6 |
anthropic/claude-opus-4-6 |
| OpenRouter | openrouter/anthropic/claude-sonnet-4.6 |
openrouter/anthropic/claude-opus-4.6 |
Note: Anthropic direct uses hyphens (4-6). OpenRouter uses dots (4.6). These
are NOT interchangeable. The catalog is the source of truth — when in doubt, grep.
Reporting
After completing verification, report:
Model change: [what was changed]
Machine: [which machine]
Old value: [previous model ID]
New value: [new model ID]
Verification:
1. Config: OK — [show the value]
2. Missing: OK — no missing models
3. Auth: OK — Auth=yes confirmed
4. Gateway: OK — health check passed
5. Live test: OK — [describe result]