Error detective
Skill felipeArnold/filament-ai-skills/skills/error-detective
Agente especializado em detectar, diagnosticar e corrigir erros no sistema. Analisa logs, browser console, exceções PHP, erros de banco de dados, erros Livewire/Filament e problemas de configuração. Ativa quando o usuário menciona: erro, exception, bug, falha, não funciona, quebrou, 500, 404, null, undefined, stack trace, log, error, crash, problema, não atualiza, não salva, tela branca.From its SKILL.md
npx -y skills add felipeArnold/filament-ai-skills --skill error-detectiveAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.9 KB, as published. Nobody here has run it
Error Detective — Diagnóstico de Erros do Sistema
Objetivo
Localizar, diagnosticar e corrigir erros no sistema de forma sistemática. Nunca pule etapas — leia os logs reais antes de sugerir correções.
Protocolo de Diagnóstico (5 Etapas)
Etapa 1 — Coletar evidências
Execute em paralelo:
# Últimas linhas do log Laravel
tail -n 100 storage/logs/laravel.log
# Logs do Horizon (se jobs envolvidos)
php artisan horizon:status
Usando as ferramentas MCP disponíveis:
browser-logs— capturar erros do console do browsertinker— executar PHP para testar código suspeitodatabase-query— verificar estado dos dados no banco
Etapa 2 — Classificar o erro
| Tipo | Sintomas | Onde investigar |
|---|---|---|
| PHP Exception | Stack trace no log | storage/logs/laravel.log |
| Livewire/Filament | Erro no console, ação sem resposta | browser-logs + log Laravel |
| Banco de dados | SQLSTATE, constraint violation | Log Laravel + database-query |
| Null safe | ErrorException: Attempt to read property on null | Código + migration para verificar nullable |
| Filament path | Total não atualiza em Repeater | Ver guideline repeater-calculations.md |
| N+1 | Timeout, lentidão extrema | Telescope ou log de queries |
| Fila/Job | Dados não processados, status preso | php artisan horizon:status + log |
| Permissão | 403, acesso negado | Policy + UserRole enum |
| Frontend | CSS/JS não atualizado | npm run build ou npm run dev |
| MySQL GROUP BY | SQLSTATE[42000] only_full_group_by em Filament widget | Ver erro #9 — subquery wrapper |
Etapa 3 — Localizar o código
Para cada erro identificado:
# Buscar por padrão de código suspeito
grep -rn "NomeDoMetodo\|NomeDaClasse" app/
# Verificar arquivo específico da stack trace
# Linha exata apontada pelo stack trace é o ponto de partida
Ferramentas:
Grep— buscar padrão no códigoRead— ler arquivo com contexto da linha do errotinker— reproduzir o erro isoladamente
Etapa 4 — Diagnosticar causa raiz
Não corrija sintomas. Identifique a causa raiz antes.
Perguntas-guia:
- O erro acontece sempre ou em condições específicas? (dados específicos, usuário, tenant)
- Quando começou? (correlacionar com commits recentes)
- Há relação com nullable FK? (verificar migration)
- O dado existe no banco? (
database-query) - É um problema de estado Livewire? (re-render, hydration)
Etapa 5 — Corrigir e verificar
- Aplicar correção mínima e focada
- Executar testes relacionados:
php artisan test --compact --filter=NomeDoTest - Verificar logs após correção
vendor/bin/pint --dirtyantes de commitar
Erros Mais Comuns neste Projeto
1. Repeater total não atualiza ao deletar item
Causa: afterStateUpdated do Repeater usa paths ../../campo mas o $get já está no nível root.
Solução: Ver guideline repeater-calculations.md — passar prefix: '' para o Repeater.
->afterStateUpdated(function ($get, $set): void {
self::recalculateTotals($get, $set, ''); // '' para nível root
})
2. ErrorException: Attempt to read property on null
Causa: Acesso a relação nullable sem ?->.
Diagnóstico:
# Verificar se FK é nullable na migration
grep -n "nullable\|->foreign" database/migrations/*_create_table.php
Solução:
// ERRADO
$record->person->name
// CORRETO (FK nullable)
$record->person?->name
3. Formatação monetária retornando valor errado
Causa: O valor não foi convertido de string pt-BR (com vírgula) para float antes de formatar.
Solução:
use Illuminate\Support\Number;
// ERRADO — passa string pt-BR direto para Number::currency()
$set('total', Number::currency((float) $get('unit_price'), 'BRL'));
// CORRETO — converte para decimal primeiro
$unitPrice = (float) str_replace(['.', ','], ['', '.'], $get('unit_price'));
$set('total', Number::currency($unitPrice * $qty, 'BRL'));
4. Multi-tenancy: dados de outro tenant visíveis
Causa: Query sem escopo de tenant.
Diagnóstico:
// tinker
Tenant::find($tenantId)->orders()->count();
Order::where('tenant_id', $tenantId)->count();
Solução: Verificar se o model tem global scope ou se o resource usa ->modifyQueryUsing().
5. Action não executa / modal fecha sem ação
Causa: Falta de parent::setUp() em setUp(), ou ->action() não configurado.
Solução:
protected function setUp(): void
{
parent::setUp(); // OBRIGATÓRIO como primeira linha
$this->action(fn (array $data) => $this->execute($data));
}
6. Namespace errado em Filament v5
Causa: Confundir namespaces de Form fields, Layout e Infolist.
| Tipo | Namespace correto |
|---|---|
| Form fields (TextInput, Select) | Filament\Forms\Components\ |
| Layout (Section, Grid, Tabs) | Filament\Schemas\Components\ |
| Infolist entries (TextEntry) | Filament\Infolists\Components\ |
| Actions | Filament\Actions\ |
| Schema method | Filament\Schemas\Schema |
| Get/Set utilities | Filament\Schemas\Components\Utilities\ |
7. Job preso / não processado
Diagnóstico:
php artisan horizon:status
php artisan queue:failed
php artisan queue:failed --queue=nome_da_fila
Solução:
# Tentar re-executar
php artisan queue:retry all
# Ver detalhes do job falhado
php artisan queue:failed-table
8. Vite/Frontend não atualiza
Sintoma: CSS ou JS não reflete mudanças.
Solução: Pedir ao usuário para executar npm run build ou npm run dev.
9. SQLSTATE[42000]: only_full_group_by — Filament TableWidget com GROUP BY
Causa: Filament TableWidget adiciona automaticamente ORDER BY tabela.id ASC como tiebreaker de paginação. Em MySQL com only_full_group_by, esse id não está no GROUP BY nem é um agregado — query rejeitada.
Sintoma típico no erro:
SQLSTATE[42000]: ... Expression #2 of ORDER BY clause is not in GROUP BY clause
... order by total_revenue desc, profitability_items.id asc
Diagnóstico: A query usa ->groupBy(...) + ->orderByDesc(...), e Filament appenda ORDER BY model.id.
Solução: Envolver a query agrupada em uma subquery com o mesmo alias da tabela. O Filament aplica seus sorts na query externa (sem GROUP BY), tornando-a compatível com only_full_group_by:
protected function getTableQuery(): Builder
{
$subQuery = MyModel::query()
->selectRaw('
grouped_col as id, // alias id = coluna agrupada
grouped_col,
SUM(value) as total,
...
')
->where(...)
->groupBy('grouped_col', 'item_name')
->orderByDesc('total')
->limit(10);
// Outer query: Filament aplica ORDER BY mymodels.id aqui,
// que referencia o 'id' do subquery (= grouped_col) — válido
return MyModel::query()
->fromSub($subQuery, 'mymodels') // alias = nome da tabela do model
->orderByDesc('total');
}
Regras:
- O alias do
fromSub()deve ser exatamente o nome da tabela do model (ex:profitability_items) - Manter o
->orderByDesc()na query externa para que o sort do Filament seja tiebreaker, não o sort primário - O
->limit()deve ficar no subquery (garante os top N antes do Filament reordenar)
Busca Específica por Tipo de Erro
Erros de null-safe em produção
grep -n "Attempt to read property\|Call to a member function.*on null" storage/logs/laravel.log | tail -20
Queries lentas / N+1
grep -n "select \*\|N+1\|QueryException" storage/logs/laravel.log | tail -20
Erros de validação Filament
grep -n "ValidationException\|validation.required\|validation.unique" storage/logs/laravel.log | tail -20
Erros de autorização
grep -n "AuthorizationException\|403\|This action is unauthorized" storage/logs/laravel.log | tail -20
Relatório de Diagnóstico
Ao concluir, gerar:
## Diagnóstico: [Descrição do Erro]
### Evidências Coletadas
- Log: [linha relevante]
- Browser: [erro do console se houver]
- Banco: [estado dos dados]
### Causa Raiz
[Explicação técnica da causa]
### Correção Aplicada
- Arquivo: [path:linha]
- Mudança: [descrição]
### Verificação
- [ ] Testes executados: `php artisan test --compact --filter=...`
- [ ] Logs verificados após correção
- [ ] Pint executado: `vendor/bin/pint --dirty`