[BUG] Telegram channels plugin polling loop dies silently, no reconnect — message delivery stops permanently
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When running Claude Code with --channels plugin:telegram@claude-plugins-official, the plugin establishes outbound TCP connections to Telegram on startup, delivers DMs successfully for a short window, then silently stops polling. Outbound connections drop from ~9 to 0 with no reconnect attempt. The agent process remains alive and responsive (verified via direct stdin), but no further DMs from the allowlisted user reach the agent's input prompt.
The agent itself doesn't crash. The Telegram → agent message path simply breaks invisibly. There is no log line, no error message, and no UI indication that delivery has stopped. From the user's perspective, the bot has just gone dead.
What Should Happen?
The plugin should either:
Maintain a robust polling loop with automatic reconnect on transient failures (network blip, Telegram-side timeout, etc.), or
Surface the disconnect to the agent / user, so the human knows delivery has stopped
Currently it does neither — the disconnect is invisible. For a documented primary interaction surface on a paid product, silent failure is a bad failure mode.
Error Messages/Logs
There are no error messages — that is part of the bug. The journal / stdout / stderr show nothing when the polling loop dies.
Diagnostic evidence captured externally:
Process is alive and healthy after the failure:
$ pgrep -fa claude
NNNNN /usr/bin/claude --channels plugin:telegram@claude-plugins-official --dangerously-skip-permissions
$ ps -o stat,wchan -p NNNNN
STAT WCHAN
Ssl+ ep_pol
Normal Node.js event-loop wait state — process is doing nothing, waiting on epoll.
Zero outbound connections to Telegram:
$ ss -tnp | grep "pid=NNNNN" | wc -l
0
At startup, the same query returned ~9 connections (the expected number for the plugin's polling + Anthropic API). They drop to 0 over time and never come back.
Direct stdin still works:
Writing to the agent's stdin via tmux send-keys (or any equivalent) reaches the input handler and the agent processes the prompt normally. Only the Telegram → agent message path is broken.
Telegram has the messages:
DMs sent from the allowlisted user show double-tick delivery in the Telegram client. The plugin simply isn't pulling them.
Steps to Reproduce
- Pair the Telegram plugin per docs (bot token in ~/.claude/channels/telegram/.env, allowlist in ~/.claude/channels/telegram/access.json with dmPolicy: "allowlist")
- Launch: claude --channels plugin:telegram@claude-plugins-official --dangerously-skip-permissions
- Send a DM from the allowlisted Telegram user — delivers correctly, agent responds in the chat
- Wait 10–30 minutes (the exact trigger condition is unclear — possibly any transient network event, possibly a Telegram-side long-poll timeout)
- Send another DM — never reaches the agent. The Telegram client shows double-ticks (delivered to Telegram's servers) but the bot does not respond.
- Verify: ss -tnp | grep "pid=$(pgrep -f 'claude --channels')" returns no rows. The plugin has stopped polling entirely.
The agent is otherwise fully alive — tmux send-keys (or any direct stdin path) into the running session still produces normal responses.
What I've ruled out
Environment variables (PATH, BUN_INSTALL, HOME, USER, TERM, LANG) — all set correctly
TTY allocation — agent has a real PTY (verified Ssl+ foreground state)
Pairing state — access.json and .env are intact, mode 600, correct allowlist
DNS — getent hosts api.telegram.org resolves
Authentication — credentials at ~/.claude/.credentials.json are valid (Max OAuth, future expiry)
--dangerously-skip-permissions flag — symptom occurs both with and without
systemd sandboxing — symptom reproduces under standalone tmux launch with no sandbox at all
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
N/A
Claude Code Version
2.1.117
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Non-interactive/CI environment
Additional Information
Hypothesis: The plugin's polling loop has no reconnect-on-disconnect logic. When the connection to Telegram's long-poll endpoint drops, the loop exits and is never restarted. The agent process doesn't crash — it just stops listening on that channel.
Workaround for affected operators: an external watchdog that periodically counts outbound connections from the claude PID and restarts the service when the count drops to 0. Belt-and-braces only — root cause is in the plugin.
Plugin version: claude-plugins-official/telegram@0.0.6 (cached at ~/.claude/plugins/cache/claude-plugins-official/telegram/0.0.6/)
Severity: Medium. The agent itself is unaffected, alternative input channels work, but Telegram is the documented primary interaction surface for --channels mode and silently failing without telemetry is a bad failure mode for a paid product.
---
Terminal context: running headless under systemd, claude wrapped in a detached tmux session, no interactive terminal. PTY provided by tmux. TERM=xterm-256color.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗