openclaw - ✅(Solved) Fix Heartbeat skipped reason 'target-none' is misleading when delivery is disabled by default [1 pull requests, 1 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#44534Fetched 2026-04-08 00:45:34
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
1
Participants
Timeline (top)
cross-referenced ×1referenced ×1

When heartbeats run with the default configuration, openclaw system heartbeat last (and gateway logs) can show:

{ "status": "skipped", "reason": "target-none" }

This is accurate (the default heartbeat delivery target is none), but the wording is misleading: it reads like the system failed to resolve a chat/session target, rather than intentionally not delivering because delivery is disabled by configuration.

Error Message

  • Heartbeat timer runs at the configured interval.
  • The last heartbeat event can report status: "skipped" with reason: "target-none".

Root Cause

This is accurate (the default heartbeat delivery target is none), but the wording is misleading: it reads like the system failed to resolve a chat/session target, rather than intentionally not delivering because delivery is disabled by configuration.

Fix Action

Fixed

PR fix notes

PR #46870: fix: rename heartbeat skip reason target-none to delivery-disabled (closes #44534)

Description (problem / solution / changelog)

Summary

  • Problem: Heartbeat skip reason target-none is misleading. Users interpret it as a routing/recipient resolution failure rather than intentional behavior when heartbeat delivery is disabled by configuration.
  • Why it matters: Users waste time debugging channels, presence, allowlists, and session routing when the behavior is by-design.
  • What changed: Renamed the skip reason from target-none to delivery-disabled in src/infra/outbound/targets.ts.
  • What did NOT change (scope boundary): No changes to heartbeat logic, delivery behavior, or configuration handling. Only the reason string was renamed.

Change Type

  • Bug fix

Scope

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #44534

User-visible / Behavior Changes

openclaw system heartbeat last now shows reason: "delivery-disabled" instead of reason: "target-none" when heartbeat delivery target is set to none (the default).

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Steps

  1. Run with default heartbeat config (target=none)
  2. Check openclaw system heartbeat last

Expected

  • Shows reason: "delivery-disabled"

Actual (before fix)

  • Shows reason: "target-none"

Evidence

  • Failing test/log before + passing after
  • All 25 heartbeat tests pass with updated expectations

Human Verification

  • Verified scenarios: oxlint clean, all heartbeat tests pass (25/25)
  • Edge cases checked: only the reason string changed, no logic changes
  • What you did NOT verify: runtime end-to-end testing with actual service

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.

Compatibility / Migration

  • Backward compatible? Yes (reason string is informational, not used for logic)
  • Config/env changes? No
  • Migration needed? No

Failure Recovery

  • How to disable/revert: revert this commit

Risks and Mitigations

None

Changed files

  • src/infra/heartbeat-runner.returns-default-unset.test.ts (modified, +3/-3)
  • src/infra/outbound/targets.ts (modified, +1/-1)

Code Example

{ "status": "skipped", "reason": "target-none" }
RAW_BUFFERClick to expand / collapse

Summary

When heartbeats run with the default configuration, openclaw system heartbeat last (and gateway logs) can show:

{ "status": "skipped", "reason": "target-none" }

This is accurate (the default heartbeat delivery target is none), but the wording is misleading: it reads like the system failed to resolve a chat/session target, rather than intentionally not delivering because delivery is disabled by configuration.

Why this is confusing

  • Many users interpret target-none as a routing/recipient resolution failure ("no session / no chat to deliver to"), and will start debugging channels, presence, allowlists, and session routing.
  • In reality, the behavior is by-design unless agents.defaults.heartbeat.target is set (e.g. last).

Observed behavior

  • Heartbeat timer runs at the configured interval.
  • The last heartbeat event can report status: "skipped" with reason: "target-none".

Expected behavior

Any of the following would reduce confusion:

  1. Rename the reason to something explicitly configuration-related (e.g. delivery-disabled or target-config-none).
  2. Keep the reason, but include fields such as rawTarget / effectiveTarget so the CLI can display: "skipped: delivery disabled (target=none)".
  3. Update openclaw system heartbeat last output to include a human-readable hint when target=none, e.g. "Set agents.defaults.heartbeat.target=last to deliver to the last contact".

Notes

Docs state that target: "none" is the default and target: "last" routes to the last contact. The current target-none label is the confusing part.

extent analysis

Fix Plan

To address the confusion caused by the target-none reason in heartbeat logs, we will update the reason to delivery-disabled when the agents.defaults.heartbeat.target is set to none.

Code Changes

We need to modify the heartbeat logging logic to check the agents.defaults.heartbeat.target configuration and update the reason accordingly. Here's an example code snippet:

if target == 'none':
    reason = 'delivery-disabled'
    # Optional: include additional fields for clarity
    extra_fields = {'rawTarget': target, 'effectiveTarget': 'none'}
    log_heartbeat(status='skipped', reason=reason, extra_fields=extra_fields)

Alternatively, we can update the openclaw system heartbeat last output to include a human-readable hint when target=none:

if target == 'none':
    print("Set agents.defaults.heartbeat.target=last to deliver to the last contact")
    log_heartbeat(status='skipped', reason='target-none')

Configuration Changes

No configuration changes are required, but we should update the documentation to reflect the new reason and behavior.

Verification

To verify the fix, run the heartbeat with the default configuration and check the logs for the updated reason:

openclaw system heartbeat last

The output should display the new reason delivery-disabled or include a human-readable hint when target=none.

Extra Tips

  • Make sure to update the documentation to reflect the new behavior and reason.
  • Consider adding additional logging or monitoring to track heartbeat delivery issues and configuration changes.

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

Any of the following would reduce confusion:

  1. Rename the reason to something explicitly configuration-related (e.g. delivery-disabled or target-config-none).
  2. Keep the reason, but include fields such as rawTarget / effectiveTarget so the CLI can display: "skipped: delivery disabled (target=none)".
  3. Update openclaw system heartbeat last output to include a human-readable hint when target=none, e.g. "Set agents.defaults.heartbeat.target=last to deliver to the last contact".

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 Heartbeat skipped reason 'target-none' is misleading when delivery is disabled by default [1 pull requests, 1 participants]