Telegram channel plugin 0.0.6: polling never starts under plugin runtime (repro across Claude 2.1.207-2.1.210 + Bun 1.3.11/1.3.14; standalone works) — follow-up to locked #36606
Same bug as the (locked) #36606, reproduced on plugin 0.0.6 with new elimination data that narrows the cause to the plugin runtime's spawn context.
Reproduced on plugin 0.0.6 (so the all-errors retry loop that 0.0.6 added does not cover this) with extensive elimination testing. Windows 11 Pro 10.0.26200, native CLI install.
Same fingerprint: server process alive, MCP tools work, Channel notifications registered in the client log — but grammY polling never starts: no polling as @<bot> stderr line, no retry/error lines, and the bot's getUpdates queue grows unboundedly (getWebhookInfo.pending_update_count stuck at 18 for hours). A one-shot external getUpdates probe (no offset) returns data instantly instead of 409 — nothing is holding a long-poll, so bot.start() dies before its first successful getUpdates.
Eliminated (each tested tonight):
- Claude Code version: identical behavior on 2.1.207, 2.1.209, 2.1.210 (fresh server spawn each; auto-updater disabled during the bisect).
- Bun version: identical on Bun 1.3.11 and 1.3.14.
- Machine/network/env: standalone
bun -e "fetch('https://api.telegram.org')"→ 200 in <1s; standalone grammYnew Bot(token); await bot.init()from the plugin directory →init OKin 430 ms; no*_PROXY/NODE_OPTIONSenv in the session environment Claude propagates to children. - Config gates: bot is a group member, privacy mode disabled (
getMe.can_read_all_group_messages: true), session launched with--channels plugin:telegram@claude-plugins-official, access.json valid.
One consistent oddity worth a look: ~30 s after every spawn the client log showsnotifications/claude/channel/permission: <5-char-id> → allow (matched pending) — the permission handshake completes, yet polling still never begins. The dead server also holds 2-3 ESTABLISHED but idle TCP connections to api.telegram.org:443 (149.154.166.110 + the IPv6 endpoint), which looks like fetch requests that were sent (or half-sent) and never complete — consistent with bot.init()/getUpdates hanging forever inside the plugin-spawned process specifically (grammY has no default request timeout, so a hung fetch produces exactly this silent no-error state).
Since it reproduces across Claude versions and Bun versions but never standalone, the delta seems to be the plugin runtime's spawn context (stdio wiring / bun run --silent start wrapper) rather than the plugin code, Bun, or the network. Happy to run diagnostics on a debug build if useful.
3 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
RESOLVED — root cause found on our machine, and it was NOT a Claude Code bug. Closing.
A stale user-level
TELEGRAM_BOT_TOKENenvironment variable (holding a DIFFERENT bot's token — our trading bot's alerts bot) was inherited by Claude Code and passed to the plugin MCP server. Per the plugin's documented precedence, shell env beats~/.claude/channels/telegram/.env— so the plugin was silently running as the wrong bot the whole time:.envfile → correct token).replytool call landed in the WRONG bot's chat.Suggestion for the plugin (would have saved us a full night): log which token source was used (env vs file) at startup, and/or warn when a shell
TELEGRAM_BOT_TOKENoverrides a present.envfile — the override is silent and the resulting symptom (deaf bot, working outbound) points everywhere except the token. Exposing poller status (last getUpdates result / 409 counter) through a tool would also make this diagnosable in minutes.The original locked #36606 may be worth re-examining through this lens — same fingerprint can be produced by any second consumer on the token, not just a runtime bug.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.