openclaw - ✅(Solved) Fix [Bug]: Heartbeat model config is ignored unless heartbeat session has persisted override [1 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#59996Fetched 2026-04-08 02:37:46
View on GitHub
Comments
2
Participants
2
Timeline
6
Reactions
0
Author
Timeline (top)
commented ×2cross-referenced ×2labeled ×2

Heartbeat does not honor the configured agents.defaults.heartbeat.model on its own, because when the heartbeat session’s persisted providerOverride and modelOverride are removed, the next heartbeat run resolves to the primary agent model instead.

Root Cause

Heartbeat does not honor the configured agents.defaults.heartbeat.model on its own, because when the heartbeat session’s persisted providerOverride and modelOverride are removed, the next heartbeat run resolves to the primary agent model instead.

Fix Action

Fix / Workaround

  • Primary agent model in config: openai-codex/gpt-5.4
    • Heartbeat config in ~/.openclaw/openclaw.json:
      • agents.defaults.heartbeat.model = "ollama/gemma4:e4b"
      • agents.defaults.heartbeat.session = "agent:main:main:heartbeat"
    • Repro condition:
      • remove providerOverride and modelOverride from the heartbeat session entry
      • trigger the next heartbeat run
    • Workaround:
      • persist providerOverride: "ollama" and modelOverride: "gemma4:e4b" on the heartbeat session
    • Same behavior was also reproduced with ollama/qwen3.5:4b, so it did not appear specific to Gemma

PR fix notes

PR #61525: fix(subagents): deduplicate completion announce — prevent duplicate internal-context turns in parent session on retry

Description (problem / solution / changelog)

What this fixes (plain English)

When a sub-agent completed its task but the completion announcement failed partway, retrying the cleanup would re-announce the completion to the parent agent — causing duplicate messages. This fix tracks whether the announcement was already delivered and skips re-announcing on retry, only performing cleanup bookkeeping.

Technical details

Root cause: No deduplication of the completion announce flow. On retry/re-entry after a partial cleanup failure, the entire announce+inject cycle re-ran even if the parent had already received the completion message.

Fix:

  • Persist completionAnnouncedAt on the subagent run record after successful delivery
  • Skip announce injection for runs where delivery already succeeded, proceeding directly to cleanup
  • Lifecycle regression test covering retry/re-entry after successful delivery

Files changed:

  • src/agents/subagent-registry.ts — sweep integration with dedup tracking, completionAnnouncedAt persistence
  • src/agents/subagent-registry.types.ts — type definition for completionAnnouncedAt field on subagent run records
  • src/agents/subagent-registry-lifecycle.ts — announce dedup and delivery tracking logic
  • src/agents/subagent-registry-lifecycle.test.ts — lifecycle regression tests for dedup announce behavior

Related

  • Fixes #61479
  • Companion PRs: #61801 (orphan reconciliation), #61803 (heartbeat routing)

Test plan

  • 8/8 lifecycle tests pass
  • Deduped announce skips re-injection for already-delivered completions
  • Ended hook fires correctly on retry with sendFarewell: true
  • cleanupCompletedAt set correctly on dedup path

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/subagent-registry-lifecycle.test.ts (modified, +180/-0)
  • src/agents/subagent-registry-lifecycle.ts (modified, +30/-7)
  • src/agents/subagent-registry-run-manager.ts (modified, +2/-0)
  • src/agents/subagent-registry.types.ts (modified, +1/-20)

Code Example

- Config validated on the tested install: openclaw config validate --json returned {"valid":true,"path":"/Users/neo/.openclaw/openclaw.json"}
  - Tested config shows:
      - .openclaw/openclaw.json:169 primary model openai-codex/gpt-5.4
      - .openclaw/openclaw.json:223 heartbeat model ollama/gemma4:e4b
      - .openclaw/openclaw.json:224 heartbeat session agent:main:main:heartbeat
  - Observed runtime behavior:
      - after removing the heartbeat session’s persisted overrides, the next heartbeat resolved to gpt-5.4
      - after restoring the override fields, heartbeat returned to the intended local Ollama model
  - Session state evidence is in:
      - .openclaw/agents/main/sessions/sessions.json
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Heartbeat does not honor the configured agents.defaults.heartbeat.model on its own, because when the heartbeat session’s persisted providerOverride and modelOverride are removed, the next heartbeat run resolves to the primary agent model instead.

Steps to reproduce

  1. Set:
    • primary model = openai-codex/gpt-5.4
    • heartbeat model = ollama/gemma4:e4b
    • heartbeat session = agent:main:main:heartbeat
  2. Remove providerOverride and modelOverride from the heartbeat session entry.
  3. Trigger the next heartbeat run.
  4. Inspect the heartbeat session model.

Expected behavior

With agents.defaults.heartbeat.model configured to ollama/gemma4:e4b for agent:main:main:heartbeat, the expected behavior is that heartbeat runs on ollama/gemma4:e4b from config alone, without requiring persisted session-level providerOverride or modelOverride fields.

Actual behavior

After removing the heartbeat session’s persisted providerOverride and modelOverride, the next observed heartbeat run resolved back to openai-codex/gpt-5.4 instead of the configured Ollama heartbeat model, and restoring those session override fields returned heartbeat to the intended local model.

OpenClaw version

2026.4.2 (d74a122)

Operating system

macOS 15.7.4 (24G517)

Install method

Global Node installation under /opt/homebrew/lib/node_modules/openclaw (CLI launched as openclaw from that install).

Model

Configured heartbeat model under test: ollama/gemma4:e4b Observed fallback model when session overrides were removed: openai-codex/gpt-5.4

Provider / routing chain

OpenClaw CLI -> local OpenClaw gateway (loopback, token auth) -> configured provider "ollama" for heartbeat -> local Ollama model "gemma4:e4b" Observed fallback path after removing session overrides: OpenClaw heartbeat -> primary agent model "openai-codex/gpt-5.4"

Additional provider/model setup details

  • Primary agent model in config: openai-codex/gpt-5.4
    • Heartbeat config in ~/.openclaw/openclaw.json:
      • agents.defaults.heartbeat.model = "ollama/gemma4:e4b"
      • agents.defaults.heartbeat.session = "agent:main:main:heartbeat"
    • Repro condition:
      • remove providerOverride and modelOverride from the heartbeat session entry
      • trigger the next heartbeat run
    • Workaround:
      • persist providerOverride: "ollama" and modelOverride: "gemma4:e4b" on the heartbeat session
    • Same behavior was also reproduced with ollama/qwen3.5:4b, so it did not appear specific to Gemma

Logs, screenshots, and evidence

- Config validated on the tested install: openclaw config validate --json returned {"valid":true,"path":"/Users/neo/.openclaw/openclaw.json"}
  - Tested config shows:
      - .openclaw/openclaw.json:169 primary model openai-codex/gpt-5.4
      - .openclaw/openclaw.json:223 heartbeat model ollama/gemma4:e4b
      - .openclaw/openclaw.json:224 heartbeat session agent:main:main:heartbeat
  - Observed runtime behavior:
      - after removing the heartbeat session’s persisted overrides, the next heartbeat resolved to gpt-5.4
      - after restoring the override fields, heartbeat returned to the intended local Ollama model
  - Session state evidence is in:
      - .openclaw/agents/main/sessions/sessions.json

Impact and severity

Affected users/systems/channels: observed on this local OpenClaw install for the heartbeat session agent:main:main:heartbeat Severity: breaks intended heartbeat model selection unless sticky session state is preserved Frequency: reproducible in the tested scenario when providerOverride and modelOverride are removed Consequence: heartbeat runs on the primary agent model instead of the configured heartbeat model, so config alone is not a reliable source of truth

Additional information

  • OpenClaw version tested: 2026.4.2 (d74a122)
    • OS: macOS 15.7.4 (24G517)
    • Install method: global Node installation under /opt/homebrew/lib/node_modules/openclaw
    • This does not appear model-specific; it was observed with both ollama/gemma4:e4b and ollama/qwen3.5:4b
    • The issue appears to be config/session precedence rather than an Ollama runtime failure, because restoring the persisted session override returns heartbeat to the intended model

extent analysis

TL;DR

The heartbeat does not honor the configured agents.defaults.heartbeat.model when the persisted providerOverride and modelOverride are removed from the heartbeat session, causing it to fall back to the primary agent model.

Guidance

  • Verify that the agents.defaults.heartbeat.model is correctly set to the desired model (e.g., ollama/gemma4:e4b) in the ~/.openclaw/openclaw.json file.
  • Check the session state in .openclaw/agents/main/sessions/sessions.json to ensure that the providerOverride and modelOverride fields are persisted for the heartbeat session.
  • To mitigate the issue, persist the providerOverride and modelOverride fields on the heartbeat session, as this has been shown to return the heartbeat to the intended model.
  • Test the heartbeat run after removing and re-adding the providerOverride and modelOverride fields to verify the behavior.

Example

No code snippet is provided, as the issue appears to be related to configuration and session state rather than code.

Notes

The issue seems to be specific to the configuration and session state, rather than a model-specific problem. The fact that restoring the persisted session overrides returns the heartbeat to the intended model suggests that the issue is related to config/session precedence.

Recommendation

Apply the workaround by persisting the providerOverride and modelOverride fields on the heartbeat session, as this has been shown to resolve the issue. This is recommended because it allows the heartbeat to use the configured model without relying on the primary agent model.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

With agents.defaults.heartbeat.model configured to ollama/gemma4:e4b for agent:main:main:heartbeat, the expected behavior is that heartbeat runs on ollama/gemma4:e4b from config alone, without requiring persisted session-level providerOverride or modelOverride fields.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: Heartbeat model config is ignored unless heartbeat session has persisted override [1 pull requests, 2 comments, 2 participants]