Armadilhas de configuração — o que dá errado e como evitar
TL;DR
Os erros de configuração mais comuns do Claude Code se dividem em três categorias: permissões erradas (agente para a cada passo ou faz coisas perigosas sem perguntar), CLAUDE.md ineficaz (contexto ausente, desatualizado ou diluído em ruído) e segurança (secrets vazando pro git).
Cada armadilha catalogada aqui segue o mesmo padrão de diagnóstico — sintoma observável, causa mecânica, fix concreto — porque comportamento errado do agente quase nunca é aleatório: é sempre reflexo de uma configuração ausente ou mal calibrada em algum lugar da pilha.
As doze armadilhas abaixo cobrem os casos reais mais recorrentes, do allow list vazio (agente trava em tudo) ao secret commitado por engano (rotação é o único fix que conta de verdade); a seção “Casos práticos” reconstrói dois desses incidentes com a sequência completa de sintoma → decisão errada → correção.
A analogia: sintomas × causas
Configuração ruim raramente grita. Ela sussurra — o agente usa console.log em vez do logger do projeto, instala libs duplicadas, faz git push direto sem pedir confirmação. Cada comportamento errado é um sinal de uma configuração faltando ou errada.
O padrão de diagnóstico é sempre: sintoma → causa → fix.
Armadilhas comuns
Categoria 1 — Permissões
Armadilha 1 — sem allow configurado: agente para em tudo
Sintoma: o agente pede confirmação para git status, ls, wc -l, leitura de arquivos. A sessão parece ter travado após cada ação mínima.
Causa: nenhum allow no settings.json. Sem whitelist, qualquer tool call que não é trivialmente segura exige confirmação manual.
Regra: sempre configure no mínimo as operações de leitura. Elas são inofensivas e eliminam 80% das confirmações desnecessárias.
Armadilha 2 — allow muito amplo: agente faz ações perigosas
Sintoma: o agente faz git push --force, reseta branches, deleta arquivos sem pedir confirmação.
Causa:"Bash(git *)" ou "Bash(*)" no allow. Glob amplo demais — cobre exatamente os subcomandos que você queria excluir. Ver 06 - Permissões e sandboxing para o modelo de sandboxing por trás desse risco.
Fix: liste subcomandos específicos e use deny para os perigosos:
Regra: bloqueie ações perigosas específicas, não categorias inteiras.
Armadilha 4 — esquecer variações de argumento
Sintoma:npm test funciona automaticamente. npm test -- --watch pede confirmação. npm test -- --coverage também.
Causa:"Bash(npm test)" é matching exato. O glob * não está presente para cobrir argumentos extras.
Fix:
"Bash(npm test)",
"Bash(npm test -- *)",
"Bash(npm test *)"
Regra: para comandos que você frequentemente usa com flags extras, adicione sempre a versão com * no final.
Armadilha 5 — settings.json do projeto sobrescreve o global
Sintoma: as permissões de git status e git log que funcionam em outros projetos (do settings global) param de funcionar neste projeto.
Causa: o settings.json do projeto define seu próprio allow, sobrescrevendo o do global. Permissões não se acumulam automaticamente — a camada mais específica substitui.
Fix — opção A: repita o que você precisa do global:
Fix — opção B: não defina allow no projeto — apenas deny para restrições adicionais. O global continua valendo.
Categoria 2 — CLAUDE.md
Armadilha 6 — CLAUDE.md vazio ou inexistente
Sintoma: o agente usa console.log em vez do logger do projeto. Instala uma lib que já existe. Usa convenções de outro projeto (ou inventa as suas próprias).
Causa: sem CLAUDE.md, o agente opera com suposições genéricas baseadas no que é comum em projetos semelhantes.
Fix: crie .claude/CLAUDE.md com no mínimo: stack + logger correto + comandos de teste + seção ## Restrições. Ver 02 - CLAUDE.md anatomia.
Regra: a ausência de CLAUDE.md não é neutra — é ruído. O agente vai preencher os gaps com suposições.
Armadilha 7 — CLAUDE.md desatualizado
Sintoma: o agente usa Mongoose quando o projeto migrou para Prisma há 3 meses. Referencia src/utils/database.ts que foi movido para src/db/client.ts.
Causa: CLAUDE.md foi criado mas não é mantido junto com as mudanças de stack.
Fix: adicione “atualizar CLAUDE.md” à definição de done das tasks de migração de stack. Uma linha no ## Comandos ou ## Stack tem custo zero e impacto alto.
Regra: CLAUDE.md desatualizado é pior que nenhum CLAUDE.md — o agente segue instruções erradas com confiança.
Armadilha 8 — placeholders [...] não preenchidos
Sintoma: o agente se comporta de forma inconsistente ou faz perguntas que o CLAUDE.md deveria responder.
Causa: usou um template de CLAUDE.md mas não substituiu os campos marcados com [...].
Fix: antes de commitar o CLAUDE.md, busque por [ no arquivo:
grep '\[' .claude/CLAUDE.md
Se encontrar placeholders, preencha ou remova a seção.
Armadilha 9 — regras sem contexto
Sintoma: o agente segue a regra literalmente mesmo em casos que claramente são exceções razoáveis. Ou pede permissão em casos em que a regra não deveria se aplicar.
Causa: “Não use any” sem explicar por quê — o agente não tem contexto para julgar quando o edge case justifica exceção.
Fix: adicione o motivo e as exceções explícitas:
## Restrições- Não use `any` em TypeScript — use `unknown` com type guard. Razão: tivemos bugs de produção por tipagem solta (incident 2024-03). Exceção: tipos de resposta de APIs externas sem schema documentado (use `unknown` e valide com zod antes de usar).
Regra: a regra vale a razão que a explica. Sem razão, o agente não consegue julgar os casos de borda.
Armadilha 10 — CLAUDE.md muito longo e cheio de ruído
Sintoma: o agente ignora instruções que estão no CLAUDE.md, ou as aplica de forma inconsistente.
Causa: CLAUDE.md de 500 linhas com muitas instruções redundantes ou triviais. O modelo lê tudo mas presta menos atenção às partes diluídas em ruído.
Fix: revise o CLAUDE.md e remova:
Instruções que já estão óbvias no código (tipos bem definidos, nomenclatura clara)
Repetições da mesma regra em diferentes formas
Detalhes técnicos que o agente pode descobrir lendo o código
Regra: 80 linhas de alta densidade > 500 linhas com padding. O CLAUDE.md não é documentação — é briefing.
Categoria 3 — Segurança
Armadilha 11 — secrets em settings.json
Sintoma: API keys, passwords de banco de dados, tokens aparecem no histórico do git.
Causa:settings.json vai pro git. Qualquer coisa no campo env fica exposta.
Fix: use settings.local.json para qualquer coisa sensível:
Armadilha 12 — settings.local.json commitado por acidente
Sintoma:git log mostra settings.local.json sendo adicionado. Secrets no histórico.
Causa: arquivo criado antes de adicionar ao .gitignore. Ou .gitignore não incluía a entrada correta.
Fix:
# Remover do tracking sem apagar o arquivogit rm --cached .claude/settings.local.json# Adicionar ao .gitignoreecho ".claude/settings.local.json" >> .gitignore# Commitar a remoçãogit add .gitignoregit commit -m "chore: remove settings.local.json do tracking"
Se o secret já foi commitado e publicado, rotacione-o imediatamente — considere o secret comprometido mesmo após remover do git.
Diagnóstico rápido
flowchart TD
Prob["Sintoma observado"] --> Q1{"Agente pede\nconfirmação em tudo?"}
Q1 -- "sim" --> A1["settings.json tem allow?\nConfigura Read(*) + Edit(*) + git básicos"]
Q1 -- "não" --> Q2{"Agente faz ações\nperigosas sem perguntar?"}
Q2 -- "sim" --> A2["allow tem glob amplo?\nSubstitui Bash(git *) por subcomandos específicos + deny"]
Q2 -- "não" --> Q3{"Agente ignora\nconvenções do projeto?"}
Q3 -- "sim" --> A3["CLAUDE.md existe e está\natualizado? Preenche seção Restrições"]
Q3 -- "não" --> Q4{"Permissões globais\nsomem no projeto?"}
Q4 -- "sim" --> A4["settings.json do projeto\nrepete o que precisa do global"]
Q4 -- "não" --> Q5{"Secrets no git?"}
Q5 -- "sim" --> A5["Move para settings.local.json\nAdiciona ao .gitignore\nRotaciona secrets"]
Assista: Permissions, settings.json, and plan mode: making one Claude Code session safe
Canal: Tyler Renelle | Duração: ~26min | Idioma: EN
Complementa as Armadilhas 1-5 explicando o mecanismo por trás delas: permission rules não sobrescrevem entre camadas, elas se fundem (allow/deny/ask de todos os arquivos são concatenados e deduplicados), e quando um allow e um deny colidem, o deny sempre vence — mesmo que venha de uma camada “mais fraca” na hierarquia geral de settings.
Trecho de destaque [6:05]: “If you write a deny rule, that’s a wall the program enforces no matter what the model decides.”
Quando a configuração parece correta mas o comportamento é inesperado
Às vezes você tem certeza que configurou, mas o agente ainda não segue. Causas comuns:
CLAUDE.md está no lugar errado. Claude Code lê CLAUDE.md na raiz do projeto E .claude/CLAUDE.md. Se você criou em .claude/CLAUDE.md mas o agente parece ignorar, verifique se não há um CLAUDE.md desatualizado na raiz que está sendo lido primeiro e contraditando as instruções.
A sessão foi iniciada antes da mudança. Se você editou settings.json ou CLAUDE.md enquanto uma sessão estava aberta, as mudanças só entram em vigor na próxima sessão. Use /clear ou reinicie o Claude Code.
O padrão no allow não está matchando o comando real. O matching é de prefixo, não substring. "Bash(npm test)" cobre npm test mas não npm test -- --watch. Use "Bash(npm test *)" para cobrir todos os argumentos.
Conflito entre camada global e projeto. Se o global tem "deny": ["Bash(git push *)"] e o projeto precisa de push para CI, verifique se a camada local está permitindo explicitamente. Deny acumula entre camadas — um deny no global bloqueia em todos os projetos.
Comando passado com path absoluto vs relativo."Bash(find . -name *)" não cobre "Bash(find /home/user/repo -name *)". Se o agente usa path absoluto, o padrão precisa cobrir isso.
Checklist de saúde da configuração
settings.json tem allow list com operações básicas
settings.json tem deny list com ações destrutivas
.claude/CLAUDE.md existe com stack, convenções, restrições
CLAUDE.md não tem placeholders [...] não preenchidos
CLAUDE.md reflete a stack atual (nenhuma lib obsoleta mencionada)
settings.local.json está no .gitignore
Nenhum secret em settings.json
git log --all -- .claude/settings.local.json não retorna commits
Casos práticos
Caso 1 — o allow amplo demais que quase forçou um push destrutivo. Um time configurou "Bash(git *)" no allow global pensando em cobrir “todo comando git básico” de uma vez, sem revisar o que o glob realmente inclui. Semanas depois, numa sessão de limpeza de branches, o agente interpretou a instrução “sincroniza minha branch com o remoto” como justificativa suficiente para rodar git push --force — e o allow amplo deixou passar sem pedir confirmação. O incidente não chegou a sobrescrever histórico em main porque a branch de trabalho não era protegida, mas o susto expôs o problema real: Bash(git *) cobre git push --force tanto quanto git status, e o glob não distingue leitura de destruição. O fix aplicado foi exatamente o da Armadilha 2 — trocar o glob amplo por subcomandos explícitos no allow e adicionar deny cirúrgico para git push --force *, git reset --hard * e git push * main.
Caso 2 — o secret commitado que exigiu rotação, não só remoção. Um desenvolvedor criou .claude/settings.local.json com uma STRIPE_SECRET_KEY de teste antes de lembrar de adicionar o arquivo ao .gitignore. O commit foi feito, o push aconteceu, e só no dia seguinte alguém notou o arquivo no git log. A reação instintiva foi só rodar git rm --cached e considerar resolvido — mas isso remove o arquivo do tracking futuro, não do histórico: qualquer clone anterior ou fork já tem o secret nos commits antigos. O procedimento correto seguiu a Armadilha 12 até o fim: git rm --cached .claude/settings.local.json, entrada no .gitignore, commit da remoção — e rotação imediata da chave, tratando-a como comprometida independentemente de estar “só” num repositório privado. A lição que fica: para secrets, remover do git e rotacionar não são passos alternativos, são os dois obrigatórios.
Como explicar em inglês
Português
Inglês
Armadilha
Pitfall / gotcha
Sintoma
Symptom
Configuração desatualizada
Stale configuration
Permissão muito abrangente
Overly broad permission
Rotacionar secret
Rotate the secret
Frases úteis:
“Without an allow list, every Bash call prompts for confirmation — even git status. Always configure at minimum Read(), Edit(), and basic git read commands.”
“A stale CLAUDE.md is worse than no CLAUDE.md — the agent follows wrong instructions confidently.”
“If you accidentally committed secrets, assume they’re compromised and rotate them — removing from git history doesn’t make them safe.”
O que vem a seguir
Depois de rodar o checklist e reconhecer qual armadilha bateu com o seu sintoma, o próximo passo é ir na causa raiz em vez de só aplicar o fix pontual: se o problema foi permissão, revise a sintaxe completa de allow/deny antes de editar às cegas; se foi CLAUDE.md, entenda a anatomia esperada do arquivo; se foi camada sobrescrevendo camada, revisite como a hierarquia de configuração resolve conflitos entre global e projeto.