Triagem de bugs com Claude Code usando um ciclo repetível: reproduzir, minimizar, identificar causas prováveis, adicionar um teste de regressão e enviar uma correção pontual com verificações.

Bugs parecem aleatórios quando cada relato vira um mistério isolado. Você cutuca o código, tenta algumas ideias e espera que o problema desapareça. Às vezes some, mas você não aprende muito, e o mesmo problema volta em outra forma.
Triagem de bugs é o oposto. É uma forma rápida de reduzir incerteza. O objetivo não é consertar tudo imediatamente. O objetivo é transformar uma reclamação vaga em uma afirmação clara e testável, então fazer a menor mudança que prove que a afirmação é falsa.
Por isso o ciclo importa: reproduzir, minimizar, identificar causas prováveis com evidências, adicionar um teste de regressão, implementar uma correção pontual e validar. Cada passo elimina um tipo específico de adivinhação. Pular etapas costuma custar depois com correções maiores, efeitos colaterais ou bugs “corrigidos” que nunca foram realmente resolvidos.
Aqui vai um exemplo realista. Um usuário diz: “O botão Salvar às vezes não faz nada.” Sem um ciclo, você pode remexer no código da UI e mudar tempo, estado ou chamadas de rede. Com o ciclo, você primeiro transforma “às vezes” em “sempre, sob estas condições exatas”, tipo: “Depois de editar um título e rapidamente trocar de aba, Salvar fica desabilitado.” Essa única frase já é progresso.
Claude Code pode acelerar a parte de pensar: transformar relatórios em hipóteses precisas, sugerir onde olhar e propor um teste mínimo que deveria falhar. É especialmente útil para escanear código, logs e diffs recentes e gerar explicações plausíveis rapidamente.
Você ainda precisa verificar o que importa. Confirme que o bug é real no seu ambiente. Prefira evidência (logs, traces, testes falhando) em vez de uma história convincente. Mantenha a correção o menor possível, prove com um teste de regressão e valide com checagens claras para não trocar um bug por outro.
O retorno é uma correção pequena e segura que você consegue explicar, defender e evitar que regresse.
Boas correções começam com um workspace limpo e um problema único e claro. Antes de pedir qualquer coisa ao Claude, escolha um relato e reescreva como:
“Quando eu faço X, eu espero Y, mas recebo Z.”
Se você não consegue escrever essa frase, ainda não tem um bug. Tem um mistério.
Colete o básico desde o início para não ficar voltando atrás. Esses detalhes tornam as sugestões testáveis em vez de vagas: versão do app ou commit (e se é local, staging ou produção), detalhes do ambiente (SO, navegador/dispositivo, feature flags, região), entradas exatas (campos de formulário, payloads de API, ações do usuário), quem vê o problema (todos, um papel, uma conta/tenant) e o que “esperado” significa (texto, estado da UI, código de status, regra de negócio).
Depois preserve a evidência enquanto ainda está fresca. Um único timestamp pode economizar horas. Capture logs em torno do evento (cliente e servidor se possível), uma captura de tela ou gravação curta, IDs de request ou trace, timestamps exatos (com timezone) e o menor trecho de dados que dispara o problema.
Exemplo: um app React gerado por Koder.ai mostra “Pagamento realizado” mas o pedido permanece “Pendente.” Anote o papel do usuário, o ID exato do pedido, o corpo da resposta da API e as linhas de log do servidor para aquele request ID. Agora você pode pedir ao Claude para focar em um fluxo em vez de dar informações vagas.
Por fim, defina uma regra de parada. Decida o que contará como corrigido antes de começar a codar: um teste específico passando, um estado da UI mudando, um erro que não aparece mais nos logs, mais uma curta checklist de validação que você executará sempre. Isso evita “corrigir” o sintoma e enviar um novo bug.
Um relato bagunçado mistura fatos, suposições e frustração. Antes de pedir ajuda, converta‑o em uma pergunta nítida que o Claude possa responder com evidências.
Comece com um resumo de uma frase que nomeie a funcionalidade e a falha. Bom: “Salvar rascunho às vezes apaga o título no mobile.” Ruim: “Rascunhos estão quebrados.” Essa frase vira a âncora para todo o encadeamento de triagem.
Depois separe o que você viu do que esperava. Mantenha estéril e concreto: o botão exato que clicou, a mensagem na tela, a linha de log, o timestamp, o dispositivo, o navegador, a branch, o commit. Se não tiver, diga que não tem.
Uma estrutura simples que você pode colar:
Se faltam detalhes, peça‑os como perguntas sim/não para que respondam rápido: Acontece em uma conta nova? Só no mobile? Só após um refresh? Começou depois do último release? Dá para reproduzir em incógnito?
Claude também é útil como um “limpador de relatos.” Cole o relato original (incluindo texto copiado de screenshots, logs e trechos de chat) e peça:
“Reescreva isto como uma checklist estruturada. Alerte contradições. Liste os 5 fatos mais importantes que faltam como perguntas sim/não. Não chute causas ainda.”
Se um colega diz “Falha aleatoriamente”, empurre para algo testável: “Falha 2/10 no iPhone 14, iOS 17.2, ao tocar Salvar duas vezes rápido.” Agora dá para reproduzir de propósito.
Se você não consegue fazer o bug acontecer sob demanda, todo passo seguinte é suposição.
Comece reproduzindo no menor ambiente que ainda mostre o problema: build local, branch mínima, dataset pequeno, e o menor número de serviços ligado possível.
Anote os passos exatos para que outra pessoa consiga seguir sem perguntar nada. Torne copiável: comandos, IDs e payloads de exemplo exatamente como usados.
Um template simples de captura:
A frequência muda sua estratégia. Bugs “sempre” são ótimos para iteração rápida. Bugs “às vezes” geralmente apontam para timing, cache, condições de corrida ou estado oculto.
Com notas de reprodução em mãos, peça ao Claude por sondagens rápidas que reduzam incerteza sem reescrever o app. Boas sondagens são pequenas: uma linha de log direcionada ao limite que falha (inputs, outputs, estado chave), uma flag de debug para um componente, uma forma de forçar comportamento determinístico (seed de aleatoriedade, tempo fixo, worker único), um pequeno dataset seed que dispara o problema, ou um par request/response falho para reproduzir.
Exemplo: um fluxo de cadastro falha “às vezes.” Claude pode sugerir logar o ID gerado do usuário, o resultado da normalização do email e detalhes de erro de constraint unique, e então rerodar o mesmo payload 10 vezes. Se a falha ocorre só na primeira execução após deploy, é um forte indício para checar migrations, warmup de cache ou dados seed faltantes.
Uma boa reprodução é útil. Uma reprodução mínima é poderosa. Torna o bug mais rápido de entender, mais fácil de depurar e menos provável de “ser consertado” por acidente.
Remova tudo que não é necessário. Se o bug aparece após um fluxo longo de UI, encontre o caminho mais curto que ainda o dispara. Remova telas opcionais, feature flags e integrações não relacionadas até o bug sumir (você removeu algo essencial) ou continuar (você encontrou ruído).
Depois reduza os dados. Se precisa de um payload grande, tente o menor que ainda quebra. Se precisa de uma lista de 500 itens, veja se 5 falham, depois 2, depois 1. Remova campos um a um. O objetivo é o menor número de partes móveis que ainda reproduzam o bug.
Um método prático é “remover metade e retestar”:
Exemplo: uma página de checkout quebra “às vezes” ao aplicar um cupom. Você descobre que só falha quando o carrinho tem pelo menos um item com desconto, o cupom tem letras minúsculas e o frete é “retirada”. Esse é seu caso mínimo: um item com desconto, um cupom minúsculo e frete em retirada.
Quando o caso mínimo estiver claro, peça ao Claude para transformá‑lo em um scaffold de reprodução: um teste mínimo que chama a função que falha com as entradas mínimas, um script curto que acerta um endpoint com payload reduzido, ou um pequeno teste de UI que visita uma rota e executa uma ação.
Quando você consegue reproduzir o problema e tem um caso de teste pequeno, pare de chutar. Seu objetivo é chegar a uma lista curta de causas plausíveis e então provar ou refutar cada uma.
Uma regra útil é manter em três hipóteses. Se tiver mais, seu caso de teste ainda é grande demais ou suas observações são vagas.
Traduza o que você vê para onde isso pode estar acontecendo. Um sintoma de UI nem sempre é um bug de UI.
Exemplo: uma página React mostra um toast “Salvo”, mas o registro sumiu depois. Isso pode apontar para (1) estado da UI, (2) comportamento da API, ou (3) caminho de gravação no banco.
Peça ao Claude para explicar modos de falha prováveis em linguagem simples, e então pergunte qual prova confirmaria cada um. O objetivo é transformar “talvez” em “confira isto exato”.
Três hipóteses comuns e a evidência a coletar:
Mantenha notas concisas: sintoma, hipótese, evidência, veredito. Quando uma hipótese bater com os fatos, você está pronto para travar um teste de regressão e consertar só o necessário.
Um bom teste de regressão é seu cinto de segurança. Ele prova que o bug existe e diz quando você realmente consertou.
Comece escolhendo o menor teste que corresponde à falha. Se o bug só aparece quando várias partes interagem, um unit test pode não pegá‑lo.
Use unit quando uma função isolada está errada. Use integração quando a fronteira entre partes é o problema (handler + DB, ou UI + API). Use end‑to‑end apenas quando o bug depende do fluxo completo.
Antes de pedir ao Claude para escrever algo, reafirme o caso minimizado como um comportamento esperado estrito. Exemplo: “Quando o usuário salva um título vazio, a API deve retornar 400 com a mensagem ‘title required’.” Agora o teste tem um alvo claro.
Peça ao Claude para rascunhar um teste que falhe primeiro. Mantenha o setup mínimo e copie só os dados que disparam o bug. Nomeie o teste pelo que o usuário experimenta, não pela função interna.
Faça uma checagem rápida:
Quando o teste falhar pelo motivo certo, você pode implementar a correção estreita com confiança.
Com um pequeno repro e um teste de regressão falhando, resista à tentação de “limpar tudo”. O objetivo é parar o bug com a menor mudança que faça o teste passar pelo motivo correto.
Uma boa correção pontual altera a menor superfície possível. Se a falha está em uma função, corrija essa função, não o módulo inteiro. Se falta uma checagem de fronteira, adicione a checagem na fronteira, não em toda a cadeia de chamadas.
Se usar Claude para ajudar, peça duas opções de correção e compare escopo e risco. Exemplo: um formulário React quebra quando um campo está vazio:
A Opção A costuma ser a escolha de triagem: menor, mais fácil de revisar e com menos chance de quebrar outra coisa.
Para manter a correção estreita, toque o menor número de arquivos, prefira correções locais em vez de refatorações, adicione guards/validações onde o valor ruim entra e mantenha a mudança explícita com um antes/depois claro. Deixe comentários só quando a razão não for óbvia.
Exemplo concreto: um endpoint Go entra em panic quando um query param opcional falta. A correção pontual é tratar a string vazia no handler (parse com default ou retornar 400 com mensagem clara). Evite mudar utilitários compartilhados a menos que o teste de regressão prove que o bug está nesse código compartilhado.
Depois da mudança, rode o teste que falhava e um ou dois testes próximos. Se sua correção exige atualizar muitos testes não relacionados, é sinal de que a mudança é ampla demais.
Validação é onde você pega problemas fáceis de perder: uma correção que passa um teste mas quebra um caminho próximo, muda uma mensagem de erro ou adiciona uma query lenta.
Primeiro, rode novamente o teste de regressão que você adicionou. Se ele passar, rode os vizinhos mais próximos: testes no mesmo arquivo, no mesmo módulo e qualquer coisa que cubra os mesmos inputs. Bugs costumam se esconder em helpers compartilhados, parsing, checagens de fronteira ou cache, então as falhas mais relevantes geralmente aparecem perto.
Depois faça uma checagem manual rápida usando os passos do relato original. Mantenha curto e específico: mesmo ambiente, mesmos dados, mesma sequência de cliques ou chamadas de API. Se o relato era vago, teste o cenário exato que você usou para reproduzir.
Se quiser ajuda para manter o foco, peça ao Claude um plano de validação curto baseado na sua mudança e no cenário que falhava. Compartilhe qual arquivo você alterou, qual comportamento pretendeu e o que poderia ser afetado. Os melhores planos são curtos e executáveis: 5 a 8 checagens que você conclui em minutos, cada uma com pass/fail claros.
Por fim, registre o que validou no PR ou nas notas: quais testes rodou, quais passos manuais tentou e quaisquer limites (por exemplo, “não testei mobile”). Isso torna a correção mais confiável e mais fácil de revisitar depois.
A maneira mais rápida de perder tempo é aceitar uma “correção” antes de conseguir reproduzir o problema sob demanda. Se você não consegue fazê‑lo falhar de forma confiável, não sabe o que realmente melhorou.
Uma regra prática: não peça correções até poder descrever um setup repetível (passos exatos, entradas, ambiente e o que parece “errado”). Se o relato é vago, passe os primeiros minutos transformando‑o numa checklist que você consiga executar duas vezes e obter o mesmo resultado.
Consertar sem um caso reprodutível. Exija um script mínimo que “falha sempre”. Se é só “às vezes”, capture timing, tamanho de dados, flags e logs até que pare de ser aleatório.
Minimizar cedo demais. Se você reduzir o caso antes de confirmar a reprodução original, pode perder o sinal. Primeiro trave a reprodução de baseline, depois encolha uma mudança por vez.
Deixar o Claude chutar. Claude pode propor causas prováveis, mas você ainda precisa de evidência. Peça 2–3 hipóteses e as observações exatas que confirmariam ou rejeitariam cada uma (uma linha de log, um breakpoint, um resultado de query).
Testes de regressão que passam pelo motivo errado. Um teste pode “passar” porque nunca atinge o caminho que falhava. Assegure que ele falhe antes da correção e que falhe com a mensagem/asserção esperada.
Tratar sintomas em vez do gatilho. Se você adiciona um null check mas o real problema é “esse valor nunca deveria ser nulo”, pode estar escondendo um bug mais profundo. Prefira consertar a condição que cria o estado ruim.
Rode o novo teste de regressão e os passos de reprodução originais antes e depois da mudança. Se um bug de checkout só acontece quando um cupom é aplicado após mudar o frete, mantenha essa sequência completa como sua “verdade”, mesmo que o teste minimizado seja menor.
Se sua validação depende de “parece bom agora”, adicione uma checagem concreta (um log, uma métrica ou uma saída específica) para que a próxima pessoa verifique rapidamente.
Quando o tempo é curto, um loop pequeno e repetível vence debugging heroico.
Escreva a decisão final em poucas linhas para que a próxima pessoa (frequentemente você futuro) confie nela. Um formato útil é: “Causa raiz: X. Gatilho: Y. Correção: Z. Por que é segura: W. O que não mudamos: Q.”
Próximos passos: automatize o que puder (um script de repro salvo, um comando padrão de teste, um template para notas de causa raiz).
Se você constrói apps com Koder.ai (koder.ai), o Planning Mode pode ajudar a esboçar a mudança antes de tocar no código, e snapshots/rollback tornam mais fácil experimentar com segurança enquanto você resolve uma repro complicada. Depois que a correção estiver validada, você pode exportar o código‑fonte ou implantar o app atualizado, inclusive usando um domínio personalizado quando necessário.
A triagem de bugs é o hábito de transformar um relato vago em uma afirmação clara e testável, e então fazer a menor alteração que prove que a afirmação deixou de ser verdadeira.
É menos sobre “consertar tudo” e mais sobre reduzir a incerteza passo a passo: reproduzir, minimizar, formular hipóteses baseadas em evidências, adicionar um teste de regressão, corrigir de forma pontual e validar.
Porque cada etapa elimina um tipo diferente de suposição.
Reescreva como: “Quando eu faço X, eu espero Y, mas obtenho Z.”
Em seguida, colete apenas o contexto suficiente para torná-lo testável:
Comece confirmando que você consegue reproduzi‑lo no menor ambiente que ainda o mostre (frequentemente um build local com um conjunto de dados pequeno).
Se for “às vezes”, tente torná‑lo determinístico controlando variáveis:
Não avance até conseguir fazê‑lo falhar sob demanda; caso contrário, você está apenas chutando.
Minimização significa remover tudo que não é necessário mantendo o bug.
Um método prático é “remover metade e retestar”:
Encurte tanto passos (fluxo de usuário) quanto dados (payload menor, menos campos/itens) até ter o menor gatilho repetível.
Use Claude Code para acelerar a análise, não para substituir a verificação.
Boas solicitações são, por exemplo:
Depois, valide: reproduza localmente, confirme logs/traces e assegure que qualquer teste falhe pelo motivo certo.
Mantenha em três. Mais que isso geralmente significa que sua reprodução ainda é grande demais ou suas observações são vagas.
Para cada hipótese, escreva:
Escolha o menor nível de teste que corresponda à falha:
Um bom teste de regressão:
Faça a menor alteração que faça o teste de regressão falhar passar.
Regras práticas:
Se sua correção exige atualizar muitos testes não relacionados, provavelmente é ampla demais.
Use uma checklist curta que você consiga executar rapidamente:
Anote o que você executou e o que não testou para que o resultado seja confiável.
Isso força progresso e evita debugging interminável de “talvez seja X”.