hermes - ✅(Solved) Fix Bug: Webhook delivery crashes when TELEGRAM_HOME_CHANNEL is a username (not numeric chat ID) [1 pull requests]

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…

When TELEGRAM_HOME_CHANNEL is set to a Telegram username (e.g., @some_user) instead of a numeric chat ID, any webhook cross-platform delivery to Telegram crashes with ValueError: invalid literal for int() with base 10. This silently breaks all webhook-to-Telegram delivery including cron job notifications.

Error Message

ValueError: invalid literal for int() with base 10: '@some_user' ERROR gateway.platforms.base: [Webhook] Failed to deliver response after 2 retries: invalid literal for int() with base 10: '@some_user'

Root Cause

gateway/platforms/webhook.py line 760-762:

home = self.gateway_runner.config.get_home_channel(target_platform)
if home:
    chat_id = home.chat_id  # This is a string like "@some_user"

This chat_id string is then passed directly to adapter.send() which calls telegram.py line 983:

chat_id=int(chat_id),  # 💥 crashes on non-numeric strings

The HomeChannel dataclass (gateway/config.py line 81) stores chat_id as str, and from_dict() (line 95) does str(data["chat_id"]) with no validation or resolution.

TELEGRAM_HOME_CHANNEL env var (config.py line 851-857) is taken verbatim with no validation:

telegram_home = os.getenv("TELEGRAM_HOME_CHANNEL")
if telegram_home and Platform.TELEGRAM in config.platforms:
    config.platforms[Platform.TELEGRAM].home_channel = HomeChannel(
        platform=Platform.TELEGRAM,
        chat_id=telegram_home,  # No validation — accepts any string
        name=os.getenv("TELEGRAM_HOME_CHANNEL_NAME", "Home"),
    )

Fix Action

Fix / Workaround

Current Workaround

PR fix notes

PR #13274: fix(telegram): resolve @username home channel before send (#13206)

Description (problem / solution / changelog)

Summary

Closes #13206. Setting TELEGRAM_HOME_CHANNEL=@username silently breaks every webhook → Telegram delivery (cron notifications, etc.). The gateway logs ValueError: invalid literal for int() with base 10: '@some_user' and retries until giving up. Interactive Telegram sessions still work because those get a numeric chat_id off the inbound update — only webhook deliveries that fall back to the home channel hit the crash.

Ironically, Telegram's Bot API does accept @channelusername as a chat_id — it's the unconditional int(chat_id) in TelegramAdapter that rejects it.

Fix

gateway/platforms/telegram.py:

  • Add _resolve_chat_id(chat_id) -> str: returns numeric strings unchanged; resolves @username via bot.get_chat() once and caches the numeric id on the adapter (_username_chat_ids).
  • Call it at the top of send() so the existing int(chat_id) call sites all see a resolved numeric string.
  • On resolution failure, return SendResult(success=False, error=...) instead of letting the ValueError propagate.

Narrow scope: only send() is patched because that's the reported webhook-delivery path. Other int(chat_id) call sites inside the adapter are unchanged.

Test plan

  • tests/gateway/test_telegram_username_chat_id.py — 9 new tests covering numeric passthrough (including negative supergroup IDs), whitespace trimming, @username resolution, cache reuse, failure propagation, and send() integration (numeric path skips get_chat, username path resolves before send_message, resolution failure returns a clean SendResult.error).
  • Existing Telegram test suite still green (tests/gateway/test_telegram_*.py, 177 tests).

Changed files

  • gateway/platforms/telegram.py (modified, +28/-2)
  • tests/gateway/test_telegram_username_chat_id.py (added, +114/-0)

Code Example

ValueError: invalid literal for int() with base 10: '@some_user'
ERROR gateway.platforms.base: [Webhook] Failed to deliver response after 2 retries: invalid literal for int() with base 10: '@some_user'

---

home = self.gateway_runner.config.get_home_channel(target_platform)
if home:
    chat_id = home.chat_id  # This is a string like "@some_user"

---

chat_id=int(chat_id),  # 💥 crashes on non-numeric strings

---

telegram_home = os.getenv("TELEGRAM_HOME_CHANNEL")
if telegram_home and Platform.TELEGRAM in config.platforms:
    config.platforms[Platform.TELEGRAM].home_channel = HomeChannel(
        platform=Platform.TELEGRAM,
        chat_id=telegram_home,  # No validation — accepts any string
        name=os.getenv("TELEGRAM_HOME_CHANNEL_NAME", "Home"),
    )

---

deliver: telegram
deliver_extra:
  chat_id: "1234567890"

---

# In _load_env_config(), after line 857:
if telegram_home and not telegram_home.lstrip("@").isdigit():
    # Will be resolved after Telegram adapter connects
    # (deferred resolution needed since bot isn't available yet)
    logger.warning(
        "TELEGRAM_HOME_CHANNEL='%s' is not a numeric chat ID. "
        "Username resolution will be attempted after bot connects. "
        "For reliability, set TELEGRAM_HOME_CHANNEL to your numeric chat ID.",
        telegram_home,
    )

---

# Line 983, replace:
chat_id=int(chat_id),
# With:
try:
    numeric_chat_id = int(chat_id)
except (ValueError, TypeError):
    # Attempt username resolution via bot.get_chat()
    try:
        chat_obj = await self._bot.get_chat(chat_id)
        numeric_chat_id = chat_obj.id
    except Exception:
        raise ValueError(
            f"chat_id '{chat_id}' is not numeric and could not be resolved. "
            f"Telegram requires a numeric chat ID. Set TELEGRAM_HOME_CHANNEL "
            f"to your numeric ID (found via @userinfobot or channel_directory.json)."
        ) from None
RAW_BUFFERClick to expand / collapse

Summary

When TELEGRAM_HOME_CHANNEL is set to a Telegram username (e.g., @some_user) instead of a numeric chat ID, any webhook cross-platform delivery to Telegram crashes with ValueError: invalid literal for int() with base 10. This silently breaks all webhook-to-Telegram delivery including cron job notifications.

Impact

Any user who sets TELEGRAM_HOME_CHANNEL to their username (a natural thing to do) will find that:

  • Webhook deliver: telegram routes silently fail
  • Cron job notifications never arrive
  • No error is surfaced to the user — the delivery just disappears after retries

This is particularly insidious because interactive Telegram sessions work fine (the gateway already has the numeric chat_id from the Telegram update object). The bug only manifests for webhook-initiated deliveries that fall back to the home channel.

Reproduction

  1. Set TELEGRAM_HOME_CHANNEL=@some_user (or any non-numeric value) in .env
  2. Configure a webhook route with deliver: telegram (no deliver_extra.chat_id)
  3. POST to the webhook route
  4. Observe in gateway logs:
ValueError: invalid literal for int() with base 10: '@some_user'
ERROR gateway.platforms.base: [Webhook] Failed to deliver response after 2 retries: invalid literal for int() with base 10: '@some_user'

Root Cause

gateway/platforms/webhook.py line 760-762:

home = self.gateway_runner.config.get_home_channel(target_platform)
if home:
    chat_id = home.chat_id  # This is a string like "@some_user"

This chat_id string is then passed directly to adapter.send() which calls telegram.py line 983:

chat_id=int(chat_id),  # 💥 crashes on non-numeric strings

The HomeChannel dataclass (gateway/config.py line 81) stores chat_id as str, and from_dict() (line 95) does str(data["chat_id"]) with no validation or resolution.

TELEGRAM_HOME_CHANNEL env var (config.py line 851-857) is taken verbatim with no validation:

telegram_home = os.getenv("TELEGRAM_HOME_CHANNEL")
if telegram_home and Platform.TELEGRAM in config.platforms:
    config.platforms[Platform.TELEGRAM].home_channel = HomeChannel(
        platform=Platform.TELEGRAM,
        chat_id=telegram_home,  # No validation — accepts any string
        name=os.getenv("TELEGRAM_HOME_CHANNEL_NAME", "Home"),
    )

Current Workaround

Set TELEGRAM_HOME_CHANNEL to the numeric chat ID instead of the username. Can be found via the Telegram Bot API getUpdates endpoint or from ~/.hermes/channel_directory.json.

Alternatively, specify deliver_extra.chat_id explicitly in each webhook route config:

deliver: telegram
deliver_extra:
  chat_id: "1234567890"

Suggested Fix

Two changes needed:

1. Resolve usernames to numeric chat IDs at startup (gateway/config.py):

In _load_env_config(), after setting the home_channel from the env var, if the chat_id is not purely numeric, attempt to resolve it using the bot's get_chat() method (available after the Telegram adapter connects). If resolution fails, log a warning and suggest using the numeric ID.

# In _load_env_config(), after line 857:
if telegram_home and not telegram_home.lstrip("@").isdigit():
    # Will be resolved after Telegram adapter connects
    # (deferred resolution needed since bot isn't available yet)
    logger.warning(
        "TELEGRAM_HOME_CHANNEL='%s' is not a numeric chat ID. "
        "Username resolution will be attempted after bot connects. "
        "For reliability, set TELEGRAM_HOME_CHANNEL to your numeric chat ID.",
        telegram_home,
    )

2. Make telegram.py:send() resilient (gateway/platforms/telegram.py):

Add a try/except around int(chat_id) with a clear error message:

# Line 983, replace:
chat_id=int(chat_id),
# With:
try:
    numeric_chat_id = int(chat_id)
except (ValueError, TypeError):
    # Attempt username resolution via bot.get_chat()
    try:
        chat_obj = await self._bot.get_chat(chat_id)
        numeric_chat_id = chat_obj.id
    except Exception:
        raise ValueError(
            f"chat_id '{chat_id}' is not numeric and could not be resolved. "
            f"Telegram requires a numeric chat ID. Set TELEGRAM_HOME_CHANNEL "
            f"to your numeric ID (found via @userinfobot or channel_directory.json)."
        ) from None

This makes the Telegram adapter resilient to username-based chat IDs while guiding users to the proper fix.

Environment

  • hermes-agent: latest main (commit after v0.23.x)
  • OS: Ubuntu 22.04
  • Python: 3.11
  • Discovered during: email-triage webhook pipeline development
  • Gateway log evidence: ValueError: invalid literal for int() with base 10 on webhook delivery retry

extent analysis

TL;DR

To fix the issue, resolve Telegram usernames to numeric chat IDs at startup and make the Telegram adapter resilient to non-numeric chat IDs.

Guidance

  • Validate the TELEGRAM_HOME_CHANNEL environment variable to ensure it's a numeric chat ID, and attempt to resolve usernames to numeric IDs using the Telegram Bot API.
  • Modify the gateway/platforms/telegram.py file to add a try/except block around int(chat_id) and attempt to resolve the username to a numeric ID if it's not already numeric.
  • Set TELEGRAM_HOME_CHANNEL to the numeric chat ID instead of the username as a temporary workaround.
  • Specify deliver_extra.chat_id explicitly in each webhook route config as an alternative workaround.

Example

try:
    numeric_chat_id = int(chat_id)
except (ValueError, TypeError):
    # Attempt username resolution via bot.get_chat()
    try:
        chat_obj = await self._bot.get_chat(chat_id)
        numeric_chat_id = chat_obj.id
    except Exception:
        raise ValueError(
            f"chat_id '{chat_id}' is not numeric and could not be resolved. "
            f"Telegram requires a numeric chat ID. Set TELEGRAM_HOME_CHANNEL "
            f"to your numeric ID (found via @userinfobot or channel_directory.json)."
        ) from None

Notes

The suggested fix requires modifications to the gateway/config.py and gateway/platforms/telegram.py files. The changes aim to make the Telegram adapter more resilient to non-numeric chat IDs and guide users to set the correct numeric chat ID.

Recommendation

Apply the suggested fix to resolve usernames to numeric chat IDs at startup and make the Telegram adapter resilient to non-numeric chat IDs. This will ensure reliable delivery of webhook notifications to Telegram channels.

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

hermes - ✅(Solved) Fix Bug: Webhook delivery crashes when TELEGRAM_HOME_CHANNEL is a username (not numeric chat ID) [1 pull requests]