Skip to content

Multi-account heartbeat delivery ignores agent binding — always uses first/default account #9110

@claulurip-collab

Description

@claulurip-collab

Summary

When running multiple Telegram accounts (multi-agent setup with channels.telegram.accounts), heartbeat delivery for a secondary agent always routes through the wrong bot account (the primary/default one), ignoring the agent→account binding.

Setup

{
  agents: {
    list: [
      { id: "main" },
      {
        id: "fitness",
        workspace: "/path/to/fitness",
        agentDir: "~/.clawdbot/agents/fitness/agent",
        heartbeat: {
          every: "2h",
          target: "telegram",
          to: "523482352"
        }
      }
    ]
  },
  bindings: [
    { agentId: "main",    match: { channel: "telegram", accountId: "claudia" } },
    { agentId: "fitness", match: { channel: "telegram", accountId: "drmike" } }
  ],
  channels: {
    telegram: {
      accounts: {
        claudia: { botToken: "...", dmPolicy: "pairing", ... },
        drmike:  { botToken: "...", dmPolicy: "pairing", ... }
      }
    }
  }
}

Expected Behavior

The fitness agent's heartbeat should deliver through the drmike Telegram bot account, since:

  1. The binding explicitly maps fitnessdrmike
  2. target: "telegram" and to: "<user_id>" are set explicitly

Actual Behavior

Heartbeat messages from the fitness agent are delivered through the claudia bot account (the primary/default). The user receives fitness nudges from the wrong bot.

What I've Tried

  1. target: "last" (default) — requires an inbound message through the drmike bot to establish delivery context. Breaks on every restart since session delivery context is not persisted.
  2. target: "telegram" + to: "<user_id>" — still delivers through the claudia account. The heartbeat delivery system does not resolve which account to use based on agent bindings.
  3. Sending a bootstrap DM from drmike bot — outbound messages don't establish the session delivery context; only inbound messages do.
  4. Asking the user to message the drmike bot — works temporarily, but breaks again on every gateway restart.

Proposed Fix

Add an accountId field to the heartbeat config schema:

heartbeat: {
  every: "2h",
  target: "telegram",
  to: "523482352",
  accountId: "drmike"  // <-- new field
}

Alternatively, when target is set to a channel and the agent has a binding with an accountId for that channel, the heartbeat delivery should automatically resolve and use that account.

Workaround

Currently disabled the fitness heartbeat (every: "0m") as there is no reliable way to deliver through the correct account.

Environment

  • OpenClaw version: 2026.1.24-3 / 2026.2.1
  • Channel: Telegram (multi-account)
  • OS: macOS (arm64)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstaleMarked as stale due to inactivity

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions