Claude Code 官方 Telegram 插件僵尸进程踩坑分享(0.0.4->0.0.5)
- 内容介绍
- 文章标签
- 相关推荐
加入L站几天了,喜欢这边氛围,来贡献一下 debug 帖,给用 claude code telegram 官方插件的佬们做个参考
背景/问题
题主一台机器上分了 3 个不同的目录在同时跑 Claude Code,3 个账号都分别接入了 telegram bot,最近几天使用的时候发现 0 号 bot 非常不稳定,发的消息经常进不到 session 里,尝试重启 tg session 或者清理后台 telegram mcp server 僵尸进程都没用,与此同时 1 号 bot 和 2 号 bot 却都能正常回话,遂开始了排查
排查过程与证据链
1. 进程状态确认(ps aux)
三个实例均正常启动(2:31-2:32am):
| 实例 | Claude PID | bot PID | launcher PID |
|---|---|---|---|
.claude |
94315 | 94327 | 94325 |
.claude1 |
94151 | 94163 | 94161 |
.claude2 |
93990 | 94001 | 93999 |
关键异常:
- 发现两个孤儿高 CPU 进程
| PID | 命令 | PPID | 运行时长 | CPU | 状态 |
|---|---|---|---|---|---|
| 18230 | bun server.ts | 1(孤儿) | 3天17小时 | ~100% | R |
| 39394 | bun server.ts | 1(孤儿) | 1天13小时 | ~99% | R |
与正常 bot 进程状态对比:94001/94327/94163 均为 0% CPU,S+ 状态。
- RSS 内存对比
.0号 bot 进程(94327)的 RSS 内存仅 26MB,而 .1号(94163)和 .2号(94001)均在 50MB 以上。内存偏低猜测 94327 早早放弃、几乎未处理任何对话;促使题主进一步检查进程环境变量和版本代码。
| 实例 | Bot PID | RSS 内存 |
|---|---|---|
| .claude(异常) | 94327 | ~26 MB |
| .claude1(正常) | 94163 | ~50 MB+ |
| .claude2(正常) | 94001 | ~52 MB |
2. 环境变量确认(ps eww)
18230: TELEGRAM_STATE_DIR=/Users/xxx/.claude2/channels/telegram
CLAUDE_PLUGIN_ROOT=...telegram/0.0.4
→ 使用 .claude2 的 bot token
39394: TELEGRAM_STATE_DIR=/Users/xxx/.claude/channels/telegram
CLAUDE_PLUGIN_ROOT=...telegram/0.0.4
→ 使用 .claude 的 bot token
此处发现本机上同时运行着两个版本的 telegram mcp server,而且两个僵尸盗版 bot 均为 0.0.4 版本 的插件 server ,pid 不在任何 bot.pid 文件中。
3. 版本代码差异(直接读取本机 cache 中的源码)
0.0.4 的 409 处理(进程 39394/18230 使用,无退出上限 ):
for (let attempt = 1; ; attempt++) {
try {
await bot.start({...})
} catch (err) {
if (err instanceof GrammyError && err.error_code === 409) {
const delay = Math.min(1000 * attempt, 15000)
await new Promise(r => setTimeout(r, delay))
continue // 遇到 409 无限重试,无任何退出条件
}
}
}
0.0.5 的 409 处理(当前正版 bot 94327 使用,最多 8 次):
if (err instanceof GrammyError && err.error_code === 409) {
if (attempt >= 8) {
process.stderr.write(`409 Conflict persists after ${attempt} attempts — Exiting.\n`)
return // 超过 8 次退出
}
// ...
}
就此得出一个非常好笑的结论 :
- 39394(0.0.4):永远在 continue 死循环,每次等 max 15s,永不退出 → 持续消耗 CPU,永远占着 telegram 槽位
- 94327(0.0.5):8 次失败后 return 退出轮询循环 → 变成"死的" MCP server,不再尝试连接
0.0.5 修复了 0.0.4 没兜底的问题,但代价是一旦遇到真正顽固的僵尸盗版(就是 39394),正版 bot 反而率先认输,变成了死 server……
4. 清理脚本失效分析
我之前有一个一键清除所有僵尸进程的脚本 kill_telegram_mcp.sh:
pids=$(ps aux | grep -i telegram | grep -v grep | awk '{print $2}')
echo "$pids" | xargs kill -9
经过验证发现 39394 和 18230 完全不会出现在 grep 输出中 ……也就是说这个脚本根本没有清理完真正抢端口的僵尸进程= =,因为实际运行的这两个僵尸子进程命令行只有 bun server.ts,没有 telegram 关键字……只有启动时的命令(bun run --cwd .../telegram/...)才包含 telegram……
所以之前每次不干净的清理反而会不停的制造新孤儿:
grep -i telegram匹配到启动进程kill -9 launcher→ 启动进程死亡- Unix 下 kill 父进程不会杀死子进程,server.ts 被
reparent到 init(PPID=1) - 0.0.4 无 orphan watchdog → 子进程永不自终
- 新的 0.0.4 孤儿堂堂诞生
5. 网络连接状态(lsof 直接观测)
最后通过跟代理之间的链接最终确定:两个僵尸的 unix socket 对端均为 (none),父进程早已死亡,mcp 连接断开。
| 进程 | unix socket | TCP(代理 7897) | 结论 |
|---|---|---|---|
94001 .claude2 bot |
正常连接 | 有,ESTABLISHED | 正在轮询 telegram |
94327 .claude bot |
正常连接 | 无 | 未在轮询 |
| 18230 zombie | ->( none) 断开 |
无 | mcp 连接已死 |
| 39394 zombie | ->( none) 断开 |
无 | mcp 连接已死 |
未解之谜
查出来 0 号 bot 和 2 号 bot 都有 0.0.4 残留版本的僵尸进程,但是启动时 0 号 bot 被卡住了,2 号却不知为何没有被卡住,鉴于没有启动时留下的任何日志,所以这个问题不得而知了
吐槽:很歹毒的一个 bug,每次启动 tg plugin session 的时候,mcp server 就算没连上也不会给你报任何异常(右下角一闪而过那种很难看到),你退出 session 时出现异常 mcp server 没有正常关闭也不会给你报任何异常,总之就是生死都没有任何个异常,一旦你异常退出一次没注意,不清理完僵尸进程你后面都别想再正常使用了……
网友解答:--【壹】--:
加入L站几天了,喜欢这边氛围,来贡献一下 debug 帖,给用 claude code telegram 官方插件的佬们做个参考
背景/问题
题主一台机器上分了 3 个不同的目录在同时跑 Claude Code,3 个账号都分别接入了 telegram bot,最近几天使用的时候发现 0 号 bot 非常不稳定,发的消息经常进不到 session 里,尝试重启 tg session 或者清理后台 telegram mcp server 僵尸进程都没用,与此同时 1 号 bot 和 2 号 bot 却都能正常回话,遂开始了排查
排查过程与证据链
1. 进程状态确认(ps aux)
三个实例均正常启动(2:31-2:32am):
| 实例 | Claude PID | bot PID | launcher PID |
|---|---|---|---|
.claude |
94315 | 94327 | 94325 |
.claude1 |
94151 | 94163 | 94161 |
.claude2 |
93990 | 94001 | 93999 |
关键异常:
- 发现两个孤儿高 CPU 进程
| PID | 命令 | PPID | 运行时长 | CPU | 状态 |
|---|---|---|---|---|---|
| 18230 | bun server.ts | 1(孤儿) | 3天17小时 | ~100% | R |
| 39394 | bun server.ts | 1(孤儿) | 1天13小时 | ~99% | R |
与正常 bot 进程状态对比:94001/94327/94163 均为 0% CPU,S+ 状态。
- RSS 内存对比
.0号 bot 进程(94327)的 RSS 内存仅 26MB,而 .1号(94163)和 .2号(94001)均在 50MB 以上。内存偏低猜测 94327 早早放弃、几乎未处理任何对话;促使题主进一步检查进程环境变量和版本代码。
| 实例 | Bot PID | RSS 内存 |
|---|---|---|
| .claude(异常) | 94327 | ~26 MB |
| .claude1(正常) | 94163 | ~50 MB+ |
| .claude2(正常) | 94001 | ~52 MB |
2. 环境变量确认(ps eww)
18230: TELEGRAM_STATE_DIR=/Users/xxx/.claude2/channels/telegram
CLAUDE_PLUGIN_ROOT=...telegram/0.0.4
→ 使用 .claude2 的 bot token
39394: TELEGRAM_STATE_DIR=/Users/xxx/.claude/channels/telegram
CLAUDE_PLUGIN_ROOT=...telegram/0.0.4
→ 使用 .claude 的 bot token
此处发现本机上同时运行着两个版本的 telegram mcp server,而且两个僵尸盗版 bot 均为 0.0.4 版本 的插件 server ,pid 不在任何 bot.pid 文件中。
3. 版本代码差异(直接读取本机 cache 中的源码)
0.0.4 的 409 处理(进程 39394/18230 使用,无退出上限 ):
for (let attempt = 1; ; attempt++) {
try {
await bot.start({...})
} catch (err) {
if (err instanceof GrammyError && err.error_code === 409) {
const delay = Math.min(1000 * attempt, 15000)
await new Promise(r => setTimeout(r, delay))
continue // 遇到 409 无限重试,无任何退出条件
}
}
}
0.0.5 的 409 处理(当前正版 bot 94327 使用,最多 8 次):
if (err instanceof GrammyError && err.error_code === 409) {
if (attempt >= 8) {
process.stderr.write(`409 Conflict persists after ${attempt} attempts — Exiting.\n`)
return // 超过 8 次退出
}
// ...
}
就此得出一个非常好笑的结论 :
- 39394(0.0.4):永远在 continue 死循环,每次等 max 15s,永不退出 → 持续消耗 CPU,永远占着 telegram 槽位
- 94327(0.0.5):8 次失败后 return 退出轮询循环 → 变成"死的" MCP server,不再尝试连接
0.0.5 修复了 0.0.4 没兜底的问题,但代价是一旦遇到真正顽固的僵尸盗版(就是 39394),正版 bot 反而率先认输,变成了死 server……
4. 清理脚本失效分析
我之前有一个一键清除所有僵尸进程的脚本 kill_telegram_mcp.sh:
pids=$(ps aux | grep -i telegram | grep -v grep | awk '{print $2}')
echo "$pids" | xargs kill -9
经过验证发现 39394 和 18230 完全不会出现在 grep 输出中 ……也就是说这个脚本根本没有清理完真正抢端口的僵尸进程= =,因为实际运行的这两个僵尸子进程命令行只有 bun server.ts,没有 telegram 关键字……只有启动时的命令(bun run --cwd .../telegram/...)才包含 telegram……
所以之前每次不干净的清理反而会不停的制造新孤儿:
grep -i telegram匹配到启动进程kill -9 launcher→ 启动进程死亡- Unix 下 kill 父进程不会杀死子进程,server.ts 被
reparent到 init(PPID=1) - 0.0.4 无 orphan watchdog → 子进程永不自终
- 新的 0.0.4 孤儿堂堂诞生
5. 网络连接状态(lsof 直接观测)
最后通过跟代理之间的链接最终确定:两个僵尸的 unix socket 对端均为 (none),父进程早已死亡,mcp 连接断开。
| 进程 | unix socket | TCP(代理 7897) | 结论 |
|---|---|---|---|
94001 .claude2 bot |
正常连接 | 有,ESTABLISHED | 正在轮询 telegram |
94327 .claude bot |
正常连接 | 无 | 未在轮询 |
| 18230 zombie | ->( none) 断开 |
无 | mcp 连接已死 |
| 39394 zombie | ->( none) 断开 |
无 | mcp 连接已死 |
未解之谜
查出来 0 号 bot 和 2 号 bot 都有 0.0.4 残留版本的僵尸进程,但是启动时 0 号 bot 被卡住了,2 号却不知为何没有被卡住,鉴于没有启动时留下的任何日志,所以这个问题不得而知了
吐槽:很歹毒的一个 bug,每次启动 tg plugin session 的时候,mcp server 就算没连上也不会给你报任何异常(右下角一闪而过那种很难看到),你退出 session 时出现异常 mcp server 没有正常关闭也不会给你报任何异常,总之就是生死都没有任何个异常,一旦你异常退出一次没注意,不清理完僵尸进程你后面都别想再正常使用了……
加入L站几天了,喜欢这边氛围,来贡献一下 debug 帖,给用 claude code telegram 官方插件的佬们做个参考
背景/问题
题主一台机器上分了 3 个不同的目录在同时跑 Claude Code,3 个账号都分别接入了 telegram bot,最近几天使用的时候发现 0 号 bot 非常不稳定,发的消息经常进不到 session 里,尝试重启 tg session 或者清理后台 telegram mcp server 僵尸进程都没用,与此同时 1 号 bot 和 2 号 bot 却都能正常回话,遂开始了排查
排查过程与证据链
1. 进程状态确认(ps aux)
三个实例均正常启动(2:31-2:32am):
| 实例 | Claude PID | bot PID | launcher PID |
|---|---|---|---|
.claude |
94315 | 94327 | 94325 |
.claude1 |
94151 | 94163 | 94161 |
.claude2 |
93990 | 94001 | 93999 |
关键异常:
- 发现两个孤儿高 CPU 进程
| PID | 命令 | PPID | 运行时长 | CPU | 状态 |
|---|---|---|---|---|---|
| 18230 | bun server.ts | 1(孤儿) | 3天17小时 | ~100% | R |
| 39394 | bun server.ts | 1(孤儿) | 1天13小时 | ~99% | R |
与正常 bot 进程状态对比:94001/94327/94163 均为 0% CPU,S+ 状态。
- RSS 内存对比
.0号 bot 进程(94327)的 RSS 内存仅 26MB,而 .1号(94163)和 .2号(94001)均在 50MB 以上。内存偏低猜测 94327 早早放弃、几乎未处理任何对话;促使题主进一步检查进程环境变量和版本代码。
| 实例 | Bot PID | RSS 内存 |
|---|---|---|
| .claude(异常) | 94327 | ~26 MB |
| .claude1(正常) | 94163 | ~50 MB+ |
| .claude2(正常) | 94001 | ~52 MB |
2. 环境变量确认(ps eww)
18230: TELEGRAM_STATE_DIR=/Users/xxx/.claude2/channels/telegram
CLAUDE_PLUGIN_ROOT=...telegram/0.0.4
→ 使用 .claude2 的 bot token
39394: TELEGRAM_STATE_DIR=/Users/xxx/.claude/channels/telegram
CLAUDE_PLUGIN_ROOT=...telegram/0.0.4
→ 使用 .claude 的 bot token
此处发现本机上同时运行着两个版本的 telegram mcp server,而且两个僵尸盗版 bot 均为 0.0.4 版本 的插件 server ,pid 不在任何 bot.pid 文件中。
3. 版本代码差异(直接读取本机 cache 中的源码)
0.0.4 的 409 处理(进程 39394/18230 使用,无退出上限 ):
for (let attempt = 1; ; attempt++) {
try {
await bot.start({...})
} catch (err) {
if (err instanceof GrammyError && err.error_code === 409) {
const delay = Math.min(1000 * attempt, 15000)
await new Promise(r => setTimeout(r, delay))
continue // 遇到 409 无限重试,无任何退出条件
}
}
}
0.0.5 的 409 处理(当前正版 bot 94327 使用,最多 8 次):
if (err instanceof GrammyError && err.error_code === 409) {
if (attempt >= 8) {
process.stderr.write(`409 Conflict persists after ${attempt} attempts — Exiting.\n`)
return // 超过 8 次退出
}
// ...
}
就此得出一个非常好笑的结论 :
- 39394(0.0.4):永远在 continue 死循环,每次等 max 15s,永不退出 → 持续消耗 CPU,永远占着 telegram 槽位
- 94327(0.0.5):8 次失败后 return 退出轮询循环 → 变成"死的" MCP server,不再尝试连接
0.0.5 修复了 0.0.4 没兜底的问题,但代价是一旦遇到真正顽固的僵尸盗版(就是 39394),正版 bot 反而率先认输,变成了死 server……
4. 清理脚本失效分析
我之前有一个一键清除所有僵尸进程的脚本 kill_telegram_mcp.sh:
pids=$(ps aux | grep -i telegram | grep -v grep | awk '{print $2}')
echo "$pids" | xargs kill -9
经过验证发现 39394 和 18230 完全不会出现在 grep 输出中 ……也就是说这个脚本根本没有清理完真正抢端口的僵尸进程= =,因为实际运行的这两个僵尸子进程命令行只有 bun server.ts,没有 telegram 关键字……只有启动时的命令(bun run --cwd .../telegram/...)才包含 telegram……
所以之前每次不干净的清理反而会不停的制造新孤儿:
grep -i telegram匹配到启动进程kill -9 launcher→ 启动进程死亡- Unix 下 kill 父进程不会杀死子进程,server.ts 被
reparent到 init(PPID=1) - 0.0.4 无 orphan watchdog → 子进程永不自终
- 新的 0.0.4 孤儿堂堂诞生
5. 网络连接状态(lsof 直接观测)
最后通过跟代理之间的链接最终确定:两个僵尸的 unix socket 对端均为 (none),父进程早已死亡,mcp 连接断开。
| 进程 | unix socket | TCP(代理 7897) | 结论 |
|---|---|---|---|
94001 .claude2 bot |
正常连接 | 有,ESTABLISHED | 正在轮询 telegram |
94327 .claude bot |
正常连接 | 无 | 未在轮询 |
| 18230 zombie | ->( none) 断开 |
无 | mcp 连接已死 |
| 39394 zombie | ->( none) 断开 |
无 | mcp 连接已死 |
未解之谜
查出来 0 号 bot 和 2 号 bot 都有 0.0.4 残留版本的僵尸进程,但是启动时 0 号 bot 被卡住了,2 号却不知为何没有被卡住,鉴于没有启动时留下的任何日志,所以这个问题不得而知了
吐槽:很歹毒的一个 bug,每次启动 tg plugin session 的时候,mcp server 就算没连上也不会给你报任何异常(右下角一闪而过那种很难看到),你退出 session 时出现异常 mcp server 没有正常关闭也不会给你报任何异常,总之就是生死都没有任何个异常,一旦你异常退出一次没注意,不清理完僵尸进程你后面都别想再正常使用了……
网友解答:--【壹】--:
加入L站几天了,喜欢这边氛围,来贡献一下 debug 帖,给用 claude code telegram 官方插件的佬们做个参考
背景/问题
题主一台机器上分了 3 个不同的目录在同时跑 Claude Code,3 个账号都分别接入了 telegram bot,最近几天使用的时候发现 0 号 bot 非常不稳定,发的消息经常进不到 session 里,尝试重启 tg session 或者清理后台 telegram mcp server 僵尸进程都没用,与此同时 1 号 bot 和 2 号 bot 却都能正常回话,遂开始了排查
排查过程与证据链
1. 进程状态确认(ps aux)
三个实例均正常启动(2:31-2:32am):
| 实例 | Claude PID | bot PID | launcher PID |
|---|---|---|---|
.claude |
94315 | 94327 | 94325 |
.claude1 |
94151 | 94163 | 94161 |
.claude2 |
93990 | 94001 | 93999 |
关键异常:
- 发现两个孤儿高 CPU 进程
| PID | 命令 | PPID | 运行时长 | CPU | 状态 |
|---|---|---|---|---|---|
| 18230 | bun server.ts | 1(孤儿) | 3天17小时 | ~100% | R |
| 39394 | bun server.ts | 1(孤儿) | 1天13小时 | ~99% | R |
与正常 bot 进程状态对比:94001/94327/94163 均为 0% CPU,S+ 状态。
- RSS 内存对比
.0号 bot 进程(94327)的 RSS 内存仅 26MB,而 .1号(94163)和 .2号(94001)均在 50MB 以上。内存偏低猜测 94327 早早放弃、几乎未处理任何对话;促使题主进一步检查进程环境变量和版本代码。
| 实例 | Bot PID | RSS 内存 |
|---|---|---|
| .claude(异常) | 94327 | ~26 MB |
| .claude1(正常) | 94163 | ~50 MB+ |
| .claude2(正常) | 94001 | ~52 MB |
2. 环境变量确认(ps eww)
18230: TELEGRAM_STATE_DIR=/Users/xxx/.claude2/channels/telegram
CLAUDE_PLUGIN_ROOT=...telegram/0.0.4
→ 使用 .claude2 的 bot token
39394: TELEGRAM_STATE_DIR=/Users/xxx/.claude/channels/telegram
CLAUDE_PLUGIN_ROOT=...telegram/0.0.4
→ 使用 .claude 的 bot token
此处发现本机上同时运行着两个版本的 telegram mcp server,而且两个僵尸盗版 bot 均为 0.0.4 版本 的插件 server ,pid 不在任何 bot.pid 文件中。
3. 版本代码差异(直接读取本机 cache 中的源码)
0.0.4 的 409 处理(进程 39394/18230 使用,无退出上限 ):
for (let attempt = 1; ; attempt++) {
try {
await bot.start({...})
} catch (err) {
if (err instanceof GrammyError && err.error_code === 409) {
const delay = Math.min(1000 * attempt, 15000)
await new Promise(r => setTimeout(r, delay))
continue // 遇到 409 无限重试,无任何退出条件
}
}
}
0.0.5 的 409 处理(当前正版 bot 94327 使用,最多 8 次):
if (err instanceof GrammyError && err.error_code === 409) {
if (attempt >= 8) {
process.stderr.write(`409 Conflict persists after ${attempt} attempts — Exiting.\n`)
return // 超过 8 次退出
}
// ...
}
就此得出一个非常好笑的结论 :
- 39394(0.0.4):永远在 continue 死循环,每次等 max 15s,永不退出 → 持续消耗 CPU,永远占着 telegram 槽位
- 94327(0.0.5):8 次失败后 return 退出轮询循环 → 变成"死的" MCP server,不再尝试连接
0.0.5 修复了 0.0.4 没兜底的问题,但代价是一旦遇到真正顽固的僵尸盗版(就是 39394),正版 bot 反而率先认输,变成了死 server……
4. 清理脚本失效分析
我之前有一个一键清除所有僵尸进程的脚本 kill_telegram_mcp.sh:
pids=$(ps aux | grep -i telegram | grep -v grep | awk '{print $2}')
echo "$pids" | xargs kill -9
经过验证发现 39394 和 18230 完全不会出现在 grep 输出中 ……也就是说这个脚本根本没有清理完真正抢端口的僵尸进程= =,因为实际运行的这两个僵尸子进程命令行只有 bun server.ts,没有 telegram 关键字……只有启动时的命令(bun run --cwd .../telegram/...)才包含 telegram……
所以之前每次不干净的清理反而会不停的制造新孤儿:
grep -i telegram匹配到启动进程kill -9 launcher→ 启动进程死亡- Unix 下 kill 父进程不会杀死子进程,server.ts 被
reparent到 init(PPID=1) - 0.0.4 无 orphan watchdog → 子进程永不自终
- 新的 0.0.4 孤儿堂堂诞生
5. 网络连接状态(lsof 直接观测)
最后通过跟代理之间的链接最终确定:两个僵尸的 unix socket 对端均为 (none),父进程早已死亡,mcp 连接断开。
| 进程 | unix socket | TCP(代理 7897) | 结论 |
|---|---|---|---|
94001 .claude2 bot |
正常连接 | 有,ESTABLISHED | 正在轮询 telegram |
94327 .claude bot |
正常连接 | 无 | 未在轮询 |
| 18230 zombie | ->( none) 断开 |
无 | mcp 连接已死 |
| 39394 zombie | ->( none) 断开 |
无 | mcp 连接已死 |
未解之谜
查出来 0 号 bot 和 2 号 bot 都有 0.0.4 残留版本的僵尸进程,但是启动时 0 号 bot 被卡住了,2 号却不知为何没有被卡住,鉴于没有启动时留下的任何日志,所以这个问题不得而知了
吐槽:很歹毒的一个 bug,每次启动 tg plugin session 的时候,mcp server 就算没连上也不会给你报任何异常(右下角一闪而过那种很难看到),你退出 session 时出现异常 mcp server 没有正常关闭也不会给你报任何异常,总之就是生死都没有任何个异常,一旦你异常退出一次没注意,不清理完僵尸进程你后面都别想再正常使用了……

