Summary
The heartbeat.model config field is documented to allow per-heartbeat model overrides, but the setting is ignored at runtime. Heartbeats always use the main session's default model instead.
Environment
- OpenClaw version: 2026.2.9
- OS: Linux 6.8.0-100-generic
- Node: v22.22.0 / v25.6.0
Configuration
openclaw.json (relevant parts)
{
"agents": {
"defaults": {
"model": {
"primary": "moonshot/kimi-k2.5"
},
"models": {
"moonshot/kimi-k2.5": { "alias": "kimi" },
"ollama/llama3.2:3b": { "alias": "local" }
},
"heartbeat": {
"every": "1h",
"model": "ollama/llama3.2:3b",
"includeReasoning": false,
"target": "last",
"prompt": "Check: Any blockers, opportunities, or progress updates needed?"
}
}
},
"models": {
"providers": {
"ollama": {
"baseUrl": "http://localhost:11434/v1",
"api": "openai-completions",
"models": [
{
"id": "llama3.2:3b",
"name": "Llama 3.2 3B"
}
]
}
}
}
}
Expected Behavior
Heartbeats should run using ollama/llama3.2:3b (local, free) instead of moonshot/kimi-k2.5.
Actual Behavior
Heartbeats continue to use the main session's default model (kimi-k2.5).
Evidence
Config shows model is set
$ openclaw config get agents.defaults.heartbeat
{
"every": "1h",
"model": "ollama/llama3.2:3b",
"includeReasoning": false,
"target": "last",
"prompt": "Check: Any blockers, opportunities, or progress updates needed?"
}
Logs show wrong model being used
2026-02-11T21:21:07.130Z debug agent/embedded embedded run start:
runId=ee265224-6ce0-41d1-bc39-6adcb78afb3b
sessionId=df3b02a4-600e-4f08-8c23-6ef2fe812307
provider=moonshot
model=kimi-k2.5
thinking=off
messageChannel=heartbeat
Note: messageChannel=heartbeat confirms this was a heartbeat run, yet it used kimi-k2.5 instead of the configured ollama/llama3.2:3b.
What was tried
-
Verified Ollama is running and model is available:
$ curl http://localhost:11434/api/tags
# llama3.2:3b is present and working
-
Added model alias to agents.defaults.models:
"ollama/llama3.2:3b": { "alias": "local" }
-
Restarted gateway multiple times — config reloads successfully but model override is still ignored.
Workaround
Use cron jobs with --session isolated — model overrides work correctly in isolated sessions.
Impact
Users cannot use cheaper/local models for heartbeats as documented, forcing unnecessary API costs for simple periodic checks.
Documentation Reference
https://docs.openclaw.ai/gateway/heartbeat (states model field should override heartbeat model)
Summary
The
heartbeat.modelconfig field is documented to allow per-heartbeat model overrides, but the setting is ignored at runtime. Heartbeats always use the main session's default model instead.Environment
Configuration
openclaw.json (relevant parts)
{ "agents": { "defaults": { "model": { "primary": "moonshot/kimi-k2.5" }, "models": { "moonshot/kimi-k2.5": { "alias": "kimi" }, "ollama/llama3.2:3b": { "alias": "local" } }, "heartbeat": { "every": "1h", "model": "ollama/llama3.2:3b", "includeReasoning": false, "target": "last", "prompt": "Check: Any blockers, opportunities, or progress updates needed?" } } }, "models": { "providers": { "ollama": { "baseUrl": "http://localhost:11434/v1", "api": "openai-completions", "models": [ { "id": "llama3.2:3b", "name": "Llama 3.2 3B" } ] } } } }Expected Behavior
Heartbeats should run using
ollama/llama3.2:3b(local, free) instead ofmoonshot/kimi-k2.5.Actual Behavior
Heartbeats continue to use the main session's default model (
kimi-k2.5).Evidence
Config shows model is set
$ openclaw config get agents.defaults.heartbeat { "every": "1h", "model": "ollama/llama3.2:3b", "includeReasoning": false, "target": "last", "prompt": "Check: Any blockers, opportunities, or progress updates needed?" }Logs show wrong model being used
Note:
messageChannel=heartbeatconfirms this was a heartbeat run, yet it usedkimi-k2.5instead of the configuredollama/llama3.2:3b.What was tried
Verified Ollama is running and model is available:
$ curl http://localhost:11434/api/tags # llama3.2:3b is present and workingAdded model alias to
agents.defaults.models:Restarted gateway multiple times — config reloads successfully but model override is still ignored.
Workaround
Use cron jobs with
--session isolated— model overrides work correctly in isolated sessions.Impact
Users cannot use cheaper/local models for heartbeats as documented, forcing unnecessary API costs for simple periodic checks.
Documentation Reference
https://docs.openclaw.ai/gateway/heartbeat (states
modelfield should override heartbeat model)