Troubleshooting¶
Comece pela etapa em que a evidência deixa de aparecer: HTTP, receipt/fila, aplicação, provider ou painel. Anote ambiente, horário, session_id, IDs de mensagens e classe do erro. Não compartilhe .env, tokens, dados cadastrais ou traceback sem revisão. Os eventos abaixo são nomes reais encontrados no checkout.
Webhook rejeita a verificação GET¶
Sintoma: HTTP 403 com verification_failed. Causas: hub.mode incorreto, token divergente ou configuração do ambiente errado. Diagnóstico: compare os nomes dos parâmetros hub.mode, hub.verify_token, hub.challenge, URL de output e configuração Meta, sem exibir o valor do token. Onde: src/webhook_handler/app.py, função de verificação GET. Correção provável: alinhar verify token/URL e repetir somente a verificação. Escalar: responsável Meta/infra se a URL ou permissão estiver fora do alcance da equipe.
POST retorna assinatura inválida ou bad request¶
Sintoma: 401 invalid_signature e whatsapp_signature_invalid, ou 400 bad_request/bad_input. Causas: assinatura ausente/incorreta, app secret divergente, corpo alterado, JSON malformado ou payload interno usado em Cloud mode. Diagnóstico: conferir header de assinatura, bytes recebidos e configuração do modo; o log internal_payload_rejected_in_cloud_mode identifica o último caso. Onde: webhook e src/core/integrations/whatsapp/adapter.py. Correção: usar webhook Meta assinado e contrato adequado. Escalar: infra quando proxy transforma o corpo; não desligar validação para “destravar” produção.
Mensagem entrou, mas não houve resposta do agente¶
Sintoma: inbound registrado sem outbound novo. Causas: cliente em HUMAN, espera de handoff, mensagem de operador, duplicata, evento de status Meta, resposta superada ou falha no envio. Diagnóstico: estado ativo, receipt, orchestrator_event, process_message_done, immediate_turns_done, whatsapp_send_failed. Onde: webhook, orchestrator e repositories. Correção: primeiro distinguir silêncio esperado de falha; em HUMAN, a equipe responde pelo painel. Escalar: apenas se uma mensagem vigente e elegível não avançar nem tiver falha classificada. Ver fluxo de mensagens.
Mensagem foi para DLQ¶
Sintoma: backlog na fila gogenetic-agent-debounce-dlq-<ambiente>.fifo. Causas: erro repetido de processamento, configuração/payload inválido ou indisponibilidade. Diagnóstico: o template redireciona após 3 recebimentos; correlacionar messageId com bad_sqs_body, process_message_failed ou process_immediate_turn_failed. Onde: SQS e CloudWatch do orchestrator. Correção: resolver causa antes de redrive, conferir se efeitos externos já aconteceram e preservar receipts. Escalar: mantenedor do fluxo quando não houver repetição segura. Retenção DLQ é 14 dias; não é arquivo permanente.
OpenAI timeout, 4xx ou 5xx¶
Sintoma: llm_timeout, llm_4xx, llm_5xx, possivelmente llm_failure_handoff. Causas: latência, permissão/modelo/configuração inválida ou falha do provider. Diagnóstico: modelo, status HTTP, attempt, orçamento de timeout e configuração de reasoning. Onde: src/core/integrations/openai_provider/client.py. Correção: alinhar modelo/permissão/configuração; timeout e 5xx têm até 1 + LLM_RETRY_MAX tentativas no wrapper. 4xx, inclusive 429, é tratado como falha imediata pelo wrapper; o SDK pode possuir sua própria política de retries. Escalar: responsável OpenAI em falha persistente e equipe humana para a conversa já transferida. Não aumentar retries sem avaliar timeout total Lambda.
Resposta JSON do agente inválida¶
Sintoma: llm_response_parse_retry, llm_response_repair_failed ou llm_response_repair_unavailable. Causas: texto fora de {JSON}Mensagem, JSON inválido ou action incompatível. Diagnóstico: reproduzir contrato com dados fictícios, conferir prompt e parser; llm_response_repair_success indica recuperação. Onde: src/core/application/parser.py e process_message_use_case.py. Correção: corrigir prompt/contrato em alteração de código própria e adicionar regressão; nesta documentação não se muda produção. Escalar: mantenedor do agente se reparar falhar e houver handoff recorrente. Ver contrato de resposta.
Transição ilegal ou condição DynamoDB¶
Sintoma: IllegalStateTransitionError ou DynamoConditionFailedError; painel diz que atendimento mudou de estado. Causas: action inválida para o estado, finalização/assunção concorrente, versão antiga ou mensagem superada. Diagnóstico: estado anterior/atual, action e condition que falhou; correlacionar agent_loop_state_changed, agent_loop_active_session_changed e agent_loop_not_agent_owned quando presentes. Onde: domínio, sessions.py, use case. Correção: reler estado e reavaliar intenção; uma corrida perdida pode ser o comportamento correto. Escalar: desenvolvedor se houver repetição sem concorrência legítima. Não substituir escrita condicional por put cego.
CRM 401, 403 ou configuração de stage inválida¶
Sintoma: smoke blocked para 401; projeção BLOCKED, hubspot_http_failed ou stage_configuration_invalid. Causas: token/permissões, base incorreta ou mapeamento incompleto. Diagnóstico: conferir base real, SSM, pipeline e os cinco HUBSPOT_STAGE_*; terminais não podem coincidir com ativos. Onde: adapter HubSpot, worker src/crm_sync/app.py, /atendimento/crm. Correção: corrigir configuração e preparar recuperação condicional da projeção. Escalar: responsável CRM quando credencial/propriedade/etapa não corresponder ao contrato. O worker não recria automaticamente um negócio para superar erro permanente.
CRM 404 ou 409¶
Sintoma: hubspot_http_404, conflito/duplicidade, ou criação sem ID utilizável. Causas: ID removido, endpoint incompatível ou contato já existente. Diagnóstico: separar busca sem resultado de erro HTTP; consultar ID e correlation ID do provider com acesso de leitura. Onde: src/core/integrations/hubspot/client.py; testes em test_hubspot_http_client.py. Correção: o adapter tem tratamento de conflito na sincronização de contato; uma atualização de deal 404 vira bloqueio e não deve gerar POST substituto. Escalar: equipe CRM para confirmar objeto/contrato. Nunca resolver duplicidade apagando registros sem identificação inequívoca.
CRM atrasado, 429/5xx ou criação incerta¶
Sintoma: PENDING com next_attempt_at futuro ou UNCERTAIN; painel fechado e CRM ainda ativo. Causas: rate limit, rede, erro remoto ou interrupção após início de POST. Diagnóstico: scripts/diagnose_crm_sync.py, último erro, revisão/confirmada, lease e métricas. Onde: CRM_SYNC#<session_id> e worker. Correção: atualizações transitórias aguardam backoff de 1, 2, 4, 8, 16, 32 e depois 60 minutos. POST ambíguo exige conferir criação antes de nova tentativa; 429 explicitamente rejeitado pode ser repetido posteriormente. Escalar: mantenedor do sync para recuperação com etag; não existe comando de apply automático no projeto.
O worker processa por até 70 segundos antes de iniciar mais itens, tem lease de 5 minutos e HTTP limitado a 10 segundos sem retry dentro desse cliente. A frequência SAM de 1 minuto não é SLA de sincronização. Para reparar um UNCERTAIN, pause o worker em mudança autorizada, aguarde execução/lease, confirme existência de exatamente um negócio ou ausência comprovada, preserve revisão/dados/IDs e faça atualização condicional revisada. Sem comprovação, mantenha a incerteza.
eGestor falha ou lookup é bloqueado¶
Sintoma: egestor_missing_document, egestor_customer_lookup_blocked, egestor_lookup_unsafe, egestor_lookup_ambiguous, egestor_lookup_invalid_response ou falha HTTP. Causas: documento ausente, resposta não comprova identidade, duplicidade, paginação incompleta ou credenciais/contrato. Diagnóstico: classe do erro e status, sem expor documento; conferir payload builder e resposta sanitizada. Onde: src/core/integrations/egestor/client.py, métrica UnsafeCustomerLookup. Correção: esclarecer contrato/identidade do cadastro antes de autorizar upsert; bloqueio evita atualizar outro cliente. Escalar: equipe eGestor/negócio quando houver ambiguidade. Veja integração; smoke sem write não comprova autenticação real.
Operador não recebe handoff¶
Sintoma: cliente aguarda, nenhum aviso chega. Causas: sem operador disponível hoje, removido da whitelist, fuso incorreto, notificador desabilitado/stub, entrega Meta falha. Diagnóstico: handoff_queued, handoff_operator_notified, handoff_notify_failed e handoff_notify_exception; comparar disponibilidade e whitelist efetivas. Onde: operator_availability.py, notificador WhatsApp e painel. Correção: operador autorizado envia entrar; revisar a configuração e a janela de WhatsApp se envio falhar. Escalar: operação se não houver equipe; integração se falhar entrega com elegibilidade correta. Slots HANDOFF_OPERATOR_* isolados não concedem acesso.
Acesso expira ou envio humano falha¶
Sintoma: login 400, ação 401/403, janela encerrada ou envio concorrente. Causas: link já usado, dia virou, whitelist/CSRF, falta de inbound recente, lock vivo. Diagnóstico: cookies/HTTPS e estado sem copiar tokens; ler aviso do painel. Onde: operator_auth.py, human_conversation.py, rotas /atendimento. Correção: novo entrar, recarregar formulário e aguardar envio atual; janela fechada exige nova mensagem do cliente. Escalar: human_message_transcript_persist_failed exige suporte ao registro; não reenviar, pois o cliente já recebeu. O lock expira em 90 segundos se a liberação falhar.
Dashboard não inicia ou health diverge da UI¶
Sintoma: porta fechada, erro de import, 404 na raiz ou chat falha apesar de health 200. Causas: venv errado, extra dev ausente, porta ocupada, DEV_UI_ENABLED=false ou key/modelo inválido. Diagnóstico: iniciar python scripts/dashboard.py em primeiro plano; no Windows, ver gogenetic-dashboard.log e .err.log; Linux/macOS, /tmp/gogenetic-dashboard.log. Onde: launchers, runner e emulator_chat_failed. Correção: alinhar venv, flags e porta; health só comprova HTTP. Escalar: erro de aplicação reproduzível após eliminar setup. Launchers podem imprimir prefixo da chave; sanitize logs.
DynamoDB Local indisponível ou tabela não encontrada¶
Sintoma: EndpointConnectionError ou ResourceNotFoundException. Causas: endpoint local não iniciado, região/tabela errada, execução do app direto sem bootstrap ou env desviando moto. Diagnóstico: distinguir runner moto de execução contra DynamoDB Local/AWS; conferir DYNAMODB_TABLE, região e apenas nomes de endpoint. Onde: scripts/dashboard.py, tests/conftest.py, factory de dependências. Correção: usar o runner para desenvolvimento em memória, ou provisionar a tabela/serviço local do fluxo escolhido. Escalar: infra em recurso real ausente; não recriar uma tabela de produção para ocultar erro de configuração.
Deploy falha ou configuração não chegou à Lambda¶
Sintoma: validação falha, CloudFormation rollback, provider aparece desligado. Causas: arquivo incompleto, modelos/parâmetros omitidos, stack/ambiente trocados, SSM/IAM ou build antigo. Diagnóstico: -ValidateOnly e eventos CloudFormation; consultar apenas subconjunto não secreto de configuração Lambda. Onde: deploy_from_env.ps1, SAM e runbook de deploy. Correção: corrigir causa, revisar parâmetros e gerar build atual; lembrar que SSM já pode ter sido alterado antes da falha. Escalar: responsável infra em rollback preso ou permissões insuficientes. Não usar exclusão da stack como recuperação.