HKUDS/Vibe-Trading · critical · ValueError
webhook_secret_token is required when Telegram mode is webho
Error message
webhook_secret_token is required when Telegram mode is webhook
What it means
Raised by TelegramChannel config validation when mode is webhook but webhook_secret_token is empty or whitespace-only. The secret token is used with Telegram's setWebhook secret_token so the bot can verify update requests actually came from Telegram. Without it, anyone who discovers the webhook URL could post forged updates, so the library refuses to start.
Source
Thrown at agent/src/channels/telegram.py:415
value = value.strip() or "/telegram"
if not value.startswith("/"):
raise ValueError('webhook_path must start with "/"')
return value
@model_validator(mode="after")
def validate_webhook_config(self) -> "TelegramConfig":
if self.mode != "webhook":
return self
url = self.webhook_url.strip()
if not url:
raise ValueError("webhook_url is required when Telegram mode is webhook")
parsed = urlparse(url)
if parsed.scheme != "https" or not parsed.netloc:
raise ValueError("webhook_url must be a public HTTPS URL")
secret = self.webhook_secret_token.strip()
if not secret:
raise ValueError("webhook_secret_token is required when Telegram mode is webhook")
if len(secret) > 256 or re.match(r"^[A-Za-z0-9_-]+$", secret) is None:
raise ValueError(
"webhook_secret_token must be 1-256 characters using only A-Z, a-z, 0-9, _ and -"
)
return self
class TelegramChannel(BaseChannel):
"""
Telegram channel using long polling or webhook mode.
Long polling is the default. Webhook mode requires a public HTTPS URL and a
Telegram secret token.
"""
name = "telegram"
display_name = "Telegram"
View on GitHub (pinned to 80ffdda44c)
Solutions
- Set webhook_secret_token to a random token, e.g. generate with openssl rand -hex 32 (matches [A-Za-z0-9_-])
- Verify the env var actually resolves in the runtime environment (print it or use the same loader the app uses)
- If you truly want polling instead of webhooks, set mode to polling rather than leaving webhook without a secret
Example fix
# before
TelegramConfig(mode="webhook", webhook_url="https://bot.example.com/tg/hook")
# after
import secrets
TelegramConfig(
mode="webhook",
webhook_url="https://bot.example.com/tg/hook",
webhook_secret_token=secrets.token_urlsafe(32),
) Defensive patterns
Strategy: validation
Validate before calling
import secrets
from agent.src.channels.telegram import TelegramConfig # adjust import
def make_tg_config(**kw) -> TelegramConfig:
if kw.get("mode") == "webhook" and not (kw.get("webhook_secret_token") or "").strip():
kw["webhook_secret_token"] = secrets.token_hex(32) # auto-provision
return TelegramConfig(**kw) Type guard
def has_webhook_secret(cfg: dict) -> bool:
return cfg.get("mode") != "webhook" or bool(str(cfg.get("webhook_secret_token", "")).strip()) Prevention
- Generate webhook secrets at deploy time with secrets.token_hex(32)
- Fail fast in CI by constructing the config object before starting the app
- Use a secrets manager that errors on missing keys rather than returning empty strings
When it happens
Trigger: Constructing the Telegram channel config with mode="webhook" (or TELEGRAAM/webhook env config) while webhook_secret_token is unset, empty, or only spaces. The model validator strips the value and raises when the result is falsy.
Common situations: Copying a polling-mode config to webhook mode and forgetting the secret; providing the secret via an env var name that isn't set (expands to empty string); secrets loaded from a .env file that isn't loaded in the deploy environment.
Related errors
- webhook_secret_token must be 1-256 characters using only A-Z
- unsafe media URL: {error}
- host is 0.0.0.0 (all interfaces) but neither token nor token
- Invalid or missing API key
- API_AUTH_KEY is required for non-local API access
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/d6c290e58be81805.
Report an issue: GitHub.