openclaw - ✅(Solved) Fix Bug: agents.defaults.heartbeat.to corrupts deliveryContext, causing private messages to leak to group with different content [1 pull requests, 1 comments, 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#65847Fetched 2026-04-14 05:40:06
View on GitHub
Comments
1
Participants
1
Timeline
2
Reactions
0
Author
Participants
Timeline (top)
commented ×1cross-referenced ×1

When agents.defaults.heartbeat.to is configured, all outgoing messages (including normal replies to user DMs) get incorrectly routed to the heartbeat target channel. Moreover, the content sent to the wrong channel is different from the content sent to the correct channel — as if two independent LLM generations occurred.

This is a privacy breach: private chat responses are leaked to a group/channel, and the leaked content may not even match what the user receives.

Root Cause

Root Cause Hypothesis

Fix Action

Fix / Workaround

Workaround (Validated ✅)

Note: This workaround is validated for single-agent setups. Multi-agent with different heartbeat targets needs further testing.

  1. Fix the routing isolation bug in agents.defaults.heartbeat handling.
  2. Document that heartbeat should be configured per-agent if routing isolation is required, or deprecate agents.defaults.heartbeat.
  3. Consider heartbeat session separation as proposed in #28639 (run heartbeats in isolated sub-sessions that don't share delivery context).
  4. Release a patch version, as this is a high-severity bug.

PR fix notes

PR #66073: Gateway/sessions: preserve shared session route on system events

Description (problem / solution / changelog)

Summary

  • stop heartbeat, cron-event, and exec-event turns from overwriting shared-session route fields
  • preserve existing session origin metadata for those synthetic turns instead of persisting synthetic provider/target values
  • add focused regressions for route-less sessions and shared-session heartbeat retargeting

Testing

  • OPENCLAW_TEST_PROFILE=serial OPENCLAW_TEST_SERIAL_GATEWAY=1 pnpm test -- src/auto-reply/reply/session.test.ts src/auto-reply/reply/session.heartbeat-no-reset.test.ts
  • pnpm build

Related

  • #63733
  • #21834
  • #35300
  • adjacent but intentionally not claimed here: #65847, #45806

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/auto-reply/reply/session.test.ts (modified, +83/-0)
  • src/auto-reply/reply/session.ts (modified, +57/-31)
  • src/config/sessions/metadata.ts (modified, +13/-2)

Code Example

{
  "agents": {
    "defaults": {
      "heartbeat": {
        "every": "30m",
        "activeHours": { "start": "08:00", "end": "22:00" },
        "target": "feishu",
        "to": "oc_8d6a0a64d5d4bb05a9f19c707c03ca6a"
      }
    }
  }
}

---

{
  "agents": {
    "defaults": {
      // Remove heartbeat from here
    },
    "list": [
      {
        "id": "main",
        // ...
        "heartbeat": {
          "every": "30m",
          "activeHours": { "start": "08:00", "end": "22:00" },
          "target": "feishu",
          "to": "oc_8d6a0a64d5d4bb05a9f19c707c03ca6a"
        }
      }
    ]
  }
}
RAW_BUFFERClick to expand / collapse

Summary

When agents.defaults.heartbeat.to is configured, all outgoing messages (including normal replies to user DMs) get incorrectly routed to the heartbeat target channel. Moreover, the content sent to the wrong channel is different from the content sent to the correct channel — as if two independent LLM generations occurred.

This is a privacy breach: private chat responses are leaked to a group/channel, and the leaked content may not even match what the user receives.

Configuration

{
  "agents": {
    "defaults": {
      "heartbeat": {
        "every": "30m",
        "activeHours": { "start": "08:00", "end": "22:00" },
        "target": "feishu",
        "to": "oc_8d6a0a64d5d4bb05a9f19c707c03ca6a"
      }
    }
  }
}

Observed Behavior

  1. User sends a DM to the agent (main)
  2. Agent generates a response intended for the DM
  3. The response appears in the heartbeat target group (oc_8d6a0a64d5d4bb05a9f19c707c03ca6a) with content A
  4. The user receives a DIFFERENT response with content B in the private chat

Or, in some cases:

  • The DM reply goes to the group
  • The heartbeat reply goes to the DM
  • Both contents are different

It appears that the routing context (deliveryContext.to) is being overwritten globally by the heartbeat configuration, and the message generation is triggered twice (once for each destination) with different outputs.

Related Issues

This is similar to but distinct from:

  • #28639 - "Heartbeat set to reply to Telegram group gets mixed up with direct chat"

    • That issue reports heartbeat messages and DM replies swapping channels.
    • My report shows ALL messages are affected, not just concurrent heartbeat+DM scenarios.
    • Also reveals content divergence (two different generations), which is not mentioned in #28639.
  • #25871 - "Heartbeat prompts incorrectly routed to Discord DMs"

    • That issue is about heartbeat prompts spamming DMs.
    • This is about private replies leaking to groups with altered content.
  • #19445 - "agents.defaults.heartbeat.model Config Ignored"

    • Shows that heartbeat config in defaults is buggy in multiple ways.
    • Supports the hypothesis that agents.defaults.heartbeat.* should not be applied globally.

Root Cause Hypothesis

When agents.defaults.heartbeat.to is set, the heartbeat's routing target is being incorrectly applied to the session's deliveryContext as a side effect. Since OpenClaw uses deliveryContext.to to determine where to send outgoing messages, all messages (not just heartbeat) get routed to the heartbeat target.

Furthermore, the system seems to queue the message for both destinations (original and heartbeat target), generating two independent LLM responses. This explains the content divergence.

Workaround (Validated ✅)

Move the heartbeat configuration from agents.defaults to the specific agent that needs it:

{
  "agents": {
    "defaults": {
      // Remove heartbeat from here
    },
    "list": [
      {
        "id": "main",
        // ...
        "heartbeat": {
          "every": "30m",
          "activeHours": { "start": "08:00", "end": "22:00" },
          "target": "feishu",
          "to": "oc_8d6a0a64d5d4bb05a9f19c707c03ca6a"
        }
      }
    ]
  }
}

Validation results (after Gateway restart):

  • ✅ Private chat replies go to the correct private chat (deliveryContext.to remains user:ou_xxx)
  • ✅ Heartbeat messages still go to the target group (to be confirmed on next heartbeat tick)
  • ✅ No duplicate messages observed in testing
  • ✅ Session count remains normal (1 active session, no extra ghost sessions)

Test method:

  1. Applied configuration change (removed heartbeat from defaults, added to main)
  2. Restarted Gateway (openclaw gateway restart)
  3. Sent test DM to agent
  4. Verified deliveryContext.to in active session points to DM, not group
  5. Checked logs: only one feishu_im_user_message: send entry for the test message
  6. No evidence of duplicate routing

Note: This workaround is validated for single-agent setups. Multi-agent with different heartbeat targets needs further testing.

Impact & Severity

  • Privacy violation: Private conversations leaked to group channels
  • Data integrity: Users receive different content than what was "sent"
  • Trust: Undermines confidence in message delivery
  • Potential compliance risk: Depending on data sensitivity

OpenClaw Version

2026.4.10 (from openclaw.json meta.lastTouchedVersion)

Request

  1. Fix the routing isolation bug in agents.defaults.heartbeat handling.
  2. Document that heartbeat should be configured per-agent if routing isolation is required, or deprecate agents.defaults.heartbeat.
  3. Consider heartbeat session separation as proposed in #28639 (run heartbeats in isolated sub-sessions that don't share delivery context).
  4. Release a patch version, as this is a high-severity bug.

Workaround Status: ✅ Validated — Configuration change applied, Gateway restarted, routing verified correct in production. Heartbeat functionality preserved. Multi-agent scenarios untested.

extent analysis

TL;DR

Move the heartbeat configuration from agents.defaults to the specific agent that needs it to prevent private chat replies from being routed to the heartbeat target channel.

Guidance

  • Remove the heartbeat configuration from agents.defaults to prevent global application of the heartbeat routing target.
  • Configure heartbeat settings per-agent to ensure routing isolation, as shown in the provided workaround example.
  • Verify that private chat replies are sent to the correct private chat and heartbeat messages are sent to the target group after applying the configuration change.
  • Test the workaround in a multi-agent setup to ensure it works as expected in all scenarios.

Example

The provided workaround example demonstrates how to move the heartbeat configuration to the specific agent:

{
  "agents": {
    "defaults": {
      // Remove heartbeat from here
    },
    "list": [
      {
        "id": "main",
        // ...
        "heartbeat": {
          "every": "30m",
          "activeHours": { "start": "08:00", "end": "22:00" },
          "target": "feishu",
          "to": "oc_8d6a0a64d5d4bb05a9f19c707c03ca6a"
        }
      }
    ]
  }
}

Notes

The workaround is validated for single-agent setups, but multi-agent scenarios require further testing. The issue is specific to OpenClaw version 2026.4.10.

Recommendation

Apply the workaround by moving the heartbeat configuration to the specific agent that needs it, as this has been validated to fix the issue.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING