Incident: Bots Telegram Mudos — Contaminação por active_profile
Data: 2026-06-13 Duração: ~8h (detectado manhã, resolvido tarde) Severidade: Alta — ambos os bots (@nexus_zimbot e @light_zimbot) ficaram sem responder Status: ✅ Resolvido
TL;DR
O arquivo ~/.hermes/active_profile ficou escrito como "light". O hermes_constants.py usa isso como fallback quando o HERMES_HOME env var não bate — mesmo com o env var certo setado no systemd unit. Resultado: o gateway do perfil default conectou ao Telegram usando o token do perfil light (@light_zimbot), ficou em polling ativo, e nunca processou as mensagens do @nexus_zimbot. Estado reportava connected (mentira) e getMe direto confirmava o bot errado conectado.
Sintomas observados
- Token funciona em teste isolado:
curl /getMe→ok: true gateway_state.json→telegram: state: "connected"- Mas o bot não respondia a
/start(nem após minutos) getUpdatesdireto →result: [](nenhuma mensagem pendente)- O outro bot do setup estava respondendo normalmente
- Log do gateway default: nenhum “Received update” relativo ao bot certo
- Service systemd:
active (running), sem crash
Diagnóstico (passo a passo)
# 1. Verificar o estado global do active_profile
cat /home/ubuntu/.hermes/active_profile
# Saiu: "light" ← PROBLEMA
# 2. Ver onde o gateway default acha que está (paths reais via /proc)
ls -la /proc/<PID_GATEWAY>/fd/ | grep -E "gateway\.log|\.env|state\.db$"
# Apareceu: /home/ubuntu/.hermes/profiles/light/state.db
# Confirmou: o default tava rodando no diretório do light
# 3. Confirmar HERMES_HOME por processo
cat /proc/<PID>/environ | tr '\0' '\n' | grep HERMES_HOME
# default: HERMES_HOME=/home/ubuntu/.hermes (env var correta)
# Mas o active_profile fez fallback pro light
# 4. Confirmar tokens em cada .env
grep TELEGRAM_BOT_TOKEN /home/ubuntu/.hermes/.env
# 828134... → @nexus_zimbot
grep TELEGRAM_BOT_TOKEN /home/ubuntu/.hermes/profiles/light/.env
# 850769... → @light_zimbotCausa raiz
O hermes_constants.py (lido por 30+ módulos no import-time) tem um fallback silencioso: se HERMES_HOME env var não bate, consulta ~/.hermes/active_profile. Se ele aponta pro perfil errado, o gateway redireciona:
config.yaml→ config do outro perfil.env→ token do outro botgateway.lock→ diretório do outro perfilgateway.log→ log do outro perfilgateway_state.json→ state do outro perfil
O systemd unit do gateway default seta HERMES_HOME=/home/ubuntu/.hermes corretamente, mas o fallback do Hermes lê o active_profile como âncora secundária. Resultado: o gateway conecta, conecta com token válido (o do light!), fica em polling, e nunca processa mensagem do @nexus_zimbot — porque a API do Telegram não entrega update pra bot que tem outro getMe.
Por que o connected mentia: python-telegram-bot faz getMe no startup, recebe sucesso (token existe, é um bot válido), e marca connected. Não tem como saber que é o bot “errado” do ponto de vista do usuário.
Correção (sequência executada)
# 1. Corrigir o active_profile
echo "default" > /home/ubuntu/.hermes/active_profile
# 2. Parar TUDO (evita crash loop durante o fix)
systemctl --user stop hermes-gateway.service hermes-gateway-light.service
# 3. Limpar locks e state files stale dos DOIS perfis
rm -f /home/ubuntu/.hermes/profiles/light/gateway.lock \
/home/ubuntu/.hermes/profiles/light/gateway.pid \
/home/ubuntu/.hermes/profiles/light/gateway_state.json \
/home/ubuntu/.hermes/gateway.lock \
/home/ubuntu/.hermes/gateway.pid \
/home/ubuntu/.hermes/gateway_state.json
# 4. Subir o light PRIMEIRO (ele é menos crítico; default costuma ter mais dependências)
systemctl --user start hermes-gateway-light.service
sleep 3
systemctl --user start hermes-gateway.service
# 5. Verificar
sleep 5
cat /home/ubuntu/.hermes/gateway_state.json | python3 -m json.tool | grep -A1 telegram
cat /home/ubuntu/.hermes/profiles/light/gateway_state.json | python3 -m json.tool | grep -A1 telegram
# Ambos devem mostrar state: "connected"
# 6. Validar que cada processo tá no diretório certo
for pid in $(pgrep -f "hermes_cli.main gateway"); do
echo "PID $pid:"
ls -la /proc/$pid/fd/ | grep -E "gateway\.log|state\.db$" | head -2
cat /proc/$pid/environ | tr '\0' '\n' | grep HERMES_HOME
doneValidação pós-fix
# Cada bot responde com seu username via getMe
cd /home/ubuntu/.hermes/hermes-agent && ./venv/bin/python3 -c "
import os, asyncio, httpx
from dotenv import load_dotenv
load_dotenv('/home/ubuntu/.hermes/.env') # e depois /profiles/light/.env
token = os.getenv('TELEGRAM_BOT_TOKEN', '')
async def t():
async with httpx.AsyncClient() as c:
r = await c.get(f'https://api.telegram.org/bot{token}/getMe')
d = r.json()
print(f'@{d[\"result\"][\"username\"]} ok={d[\"ok\"]}')
asyncio.run(t())
"
# default: @nexus_zimbot
# light: @Light_ZimBOT
# /start no @nexus_zimbot → resposta
# /start no @light_zimbot → resposta (ZimBOT-Light)Lições aprendidas
- Nunca confiar em
gateway_state.json“connected” como sinal de saúde. O bot pode estar conectado com token errado. O estado reflete “o python-telegram-bot conseguiu fazer getMe”, não “o bot certo está respondendo”. - Sempre checar
/proc/<PID>/fd/pra ver onde o processo realmente está escrevendo — é o diagnóstico mais confiável quando algo está silenciosamente errado. active_profileé uma âncora global perigosa. Mudou em qualquer lugar (heartbeat, script, setup) afeta TODOS os gateways do sistema, não só o interativo.- Testes isolados enganam.
getMeretornando ok confirma que o token é válido, não que o bot certo está respondendo. - Contaminação cross-profile é silenciosa. Não dá erro, não dá log de aviso pro usuário — só fica mudo. A skill
active-profile-contaminationfoi criada pra capturar isso.
Prevenção (recomendações)
- Adicionar check no heartbeat que valide se
active_profilebate com oHERMES_HOMEdo systemd unit do default gateway. Se não bater, alerta imediato. - Adicionar entry check na skill
hermes-troubleshootingque avise pro agente verificar isso PRIMEIRO quando o sintoma for “bot mudo mas state=connected”. - Considerar mudar o Hermes pra abortar startup se
active_profileeHERMES_HOMEdivergem. Mas é mudança no core.
Referências
- Skill nova:
~/.hermes/profiles/light/skills/hermes/active-profile-contamination/SKILL.md - Skill atualizada:
~/.hermes/profiles/light/skills/hermes/hermes-troubleshooting/SKILL.md(pointer pra nova skill) - Sessão original do bug:
20260613_041333_ae766237(deepseek-v4-flash, perfil default, 13/jun 01:13 AM) - Sessão da correção: sessão atual (MiniMax-M3, perfil light, 13/jun ~17:00)
- Source do bug no Hermes:
hermes_constants.pylinha 53-100, funçãoget_hermes_home()com fallback proactive_profile