openclaw - 💡(How to fix) Fix [Bug]: Telegram single-account with explicit empty `accounts.<X>.groups: {}` silently replaces root `channels.telegram.groups` (allowlist drops every update)

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…

For single-account Telegram setups, defining an explicit empty accounts.<acct>.groups: {} silently replaces the root channels.telegram.groups map instead of falling back to it. This is because mergeTelegramAccountConfig uses nullish coalescing (??) — {} is not nullish, so it shortcircuits the fallback.

When groupPolicy: allowlist is also set on the account, the resolved groups map becomes empty and every inbound update is dropped with reason: not-allowed, including ones that match groups defined at the root.

Error Message

This bit us during a Bot API 9.6 rollout (2026-05-08): user @mentioned the bot in our internal coordination supergroup, gateway dropped the update, the bot appeared "broken" with no surface error. Took ~30 min to trace through telegram-auto-reply logs to the merge function. A single-account user who follows the documented accounts.default shape is the most likely reporter; they are unlikely to know about the ?? semantic detail.

Root Cause

This bit us during a Bot API 9.6 rollout (2026-05-08): user @mentioned the bot in our internal coordination supergroup, gateway dropped the update, the bot appeared "broken" with no surface error. Took ~30 min to trace through telegram-auto-reply logs to the merge function. A single-account user who follows the documented accounts.default shape is the most likely reporter; they are unlikely to know about the ?? semantic detail.

Fix Action

Fix / Workaround

Workaround: copy the root channels.telegram.groups map into accounts.default.groups verbatim and restart. Then routing works.

Code Example

{
  "channels": {
    "telegram": {
      "enabled": true,
      "groupPolicy": "allowlist",
      "groupAllowFrom": ["212246892"],
      "groups": {
        "-1003221749234": {
          "requireMention": false,
          "topics": { "67": { "agentId": "social-director" } }
        }
      },
      "accounts": {
        "default": {
          "botToken": "...",
          "groupPolicy": "allowlist",
          "groups": {}                       // ← explicit empty object
        }
      }
    }
  }
}

---

{"module":"telegram-auto-reply","chatId":-1003221749234,"reason":"not-allowed"}

---

const groups = account.groups ?? (isMultiAccount ? void 0 : channelGroups);

---

const isMultiAccount = Object.keys(cfg.channels?.telegram?.accounts ?? {}).length > 1;
const accountGroupsHasEntries = account.groups && Object.keys(account.groups).length > 0;
const groups = accountGroupsHasEntries
  ? account.groups
  : (isMultiAccount ? void 0 : channelGroups);
RAW_BUFFERClick to expand / collapse

Bug type

Bug (existing functionality fails in a specific configuration)

Summary

For single-account Telegram setups, defining an explicit empty accounts.<acct>.groups: {} silently replaces the root channels.telegram.groups map instead of falling back to it. This is because mergeTelegramAccountConfig uses nullish coalescing (??) — {} is not nullish, so it shortcircuits the fallback.

When groupPolicy: allowlist is also set on the account, the resolved groups map becomes empty and every inbound update is dropped with reason: not-allowed, including ones that match groups defined at the root.

Repro

~/.openclaw/openclaw.json:

{
  "channels": {
    "telegram": {
      "enabled": true,
      "groupPolicy": "allowlist",
      "groupAllowFrom": ["212246892"],
      "groups": {
        "-1003221749234": {
          "requireMention": false,
          "topics": { "67": { "agentId": "social-director" } }
        }
      },
      "accounts": {
        "default": {
          "botToken": "...",
          "groupPolicy": "allowlist",
          "groups": {}                       // ← explicit empty object
        }
      }
    }
  }
}

Steps:

  1. openclaw gateway restart
  2. From an allowlisted user, @mention the bot in chat -1003221749234.

Expected

Update is delivered to the bound agent. The root groups entry for -1003221749234 matches and the @mention is routed.

Actual

Gateway logs:

{"module":"telegram-auto-reply","chatId":-1003221749234,"reason":"not-allowed"}

Update is silently dropped. No agent is invoked.

Workaround: copy the root channels.telegram.groups map into accounts.default.groups verbatim and restart. Then routing works.

Root cause (verified against installed source)

dist/account-config-DH-9PbIU.js line 36 (compiled from extensions/telegram/src/account-config.ts):

const groups = account.groups ?? (isMultiAccount ? void 0 : channelGroups);

account.groups = {} is not nullish, so the right side never runs. The empty object replaces channelGroups.

In a single-account setup the design intent (per #30673 and #69874) is for root groups to be inherited when the account does not define its own. An explicit {} is in practice indistinguishable from "I have not configured account-level groups" for users — there is no way for a user to opt into "force empty allowlist for this account specifically", and even if there were, it should not silently disable a valid root config.

Proposed fix

In mergeTelegramAccountConfig:

const isMultiAccount = Object.keys(cfg.channels?.telegram?.accounts ?? {}).length > 1;
const accountGroupsHasEntries = account.groups && Object.keys(account.groups).length > 0;
const groups = accountGroupsHasEntries
  ? account.groups
  : (isMultiAccount ? void 0 : channelGroups);

i.e. treat empty-object the same as undefined for the inheritance check. The multi-account suppression behavior (#30673) is preserved.

Alternative: emit a config-validation warning when accounts.<X>.groups = {} is set with groupPolicy: allowlist — at minimum the silent drop becomes diagnosable.

Why this matters

This bit us during a Bot API 9.6 rollout (2026-05-08): user @mentioned the bot in our internal coordination supergroup, gateway dropped the update, the bot appeared "broken" with no surface error. Took ~30 min to trace through telegram-auto-reply logs to the merge function. A single-account user who follows the documented accounts.default shape is the most likely reporter; they are unlikely to know about the ?? semantic detail.

Environment

  • openclaw 2026.5.3-1 (npm global install)
  • Linux 6.8.0-107-generic, Node 20.x
  • Single-account Telegram (accounts.default only)

Related

  • #30673 (the original multi-account inheritance bug — fix introduced the ?? line)
  • #69874 (WhatsApp parity follow-up)
  • #62985 (different bug, schema validation regression)

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

openclaw - 💡(How to fix) Fix [Bug]: Telegram single-account with explicit empty `accounts.<X>.groups: {}` silently replaces root `channels.telegram.groups` (allowlist drops every update)