Bug Debugger
Étape 0 — Collecter le contexte minimal
Avant toute hypothèse, s'assurer d'avoir :
| Info |
Exemples |
| Message d'erreur complet |
stack trace, code HTTP, errno |
| Comportement attendu vs observé |
"devrait retourner 200, retourne 500" |
| Reproductibilité |
toujours / parfois / en prod seulement |
| Dernière modification |
commit, déploiement, changement config |
| Environnement |
OS, version runtime, variables d'env |
Si un de ces éléments manque et bloque le diagnostic → demander uniquement ce qui est nécessaire, pas tout à la fois.
Étape 1 — Lire l'erreur sans sauter aux conclusions
TypeError: Cannot read properties of undefined (reading 'id')
at getUserName (user.js:42:18)
at processRequest (api.js:17:5)
- Lire le type d'erreur :
TypeError, NullReferenceException, SIGSEGV…
- Localiser le premier frame applicatif (ignorer les frames de libs tierces).
- Identifier l'opération qui échoue : accès propriété, appel fonction, cast, IO…
Étape 2 — Formuler 3 hypothèses classées par probabilité
Format attendu :
- (Probable)
user est undefined car la DB ne retourne rien pour cet ID → vérifier avec console.log(user) avant la ligne 42.
- (Possible) La fonction est appelée avant que la promesse soit résolue → ajouter
await.
- (Moins probable) Race condition sur un cache partagé → vérifier si ça arrive en parallèle.
Règle : ne pas proposer plus de 3 hypothèses sans validation intermédiaire.
Étape 3 — Vérification rapide par hypothèse
JavaScript/TypeScript
// Inspecter sans modifier le flux
console.log('[debug] user:', JSON.stringify(user, null, 2));
// Vérifier le type exact
console.log('[debug] typeof user:', typeof user, user instanceof Object);
Python
import pprint
print('[debug] user:', pprint.pformat(user))
# Ou avec breakpoint natif (Python 3.7+)
breakpoint()
.NET / C#
// Ajouter un point de log avant la ligne incriminée
_logger.LogDebug("user={User}", JsonSerializer.Serialize(user));
// Ou utiliser le debugger avec Watch sur l'expression
Shell / CLI
# Activer le mode verbose
set -x # bash : affiche chaque commande avant exécution
export DEBUG=* # Node.js : active les logs de debug des modules
Étape 4 — Correction
Toujours présenter un diff avant/après :
// AVANT
const name = user.profile.name;
// APRÈS — avec guard null
const name = user?.profile?.name ?? 'Inconnu';
Expliquer pourquoi la correction fonctionne, pas seulement quoi changer.
Étape 5 — Prévention
Adapter selon le contexte :
| Type de bug |
Prévention recommandée |
| Null/undefined |
TypeScript strict, optional chaining, guards |
| Race condition |
mutex, transactions, idempotence |
| Régression |
test unitaire couvrant le cas exact |
| Config manquante |
validation au démarrage (zod, pydantic) |
| Erreur silencieuse |
logger sur les catch, ne jamais catch {} vide |
Garde-fous et anti-patterns
Ne pas faire :
- Modifier le code sans reproduire le bug d'abord → on peut "corriger" la mauvaise chose.
- Ajouter plusieurs changements à la fois → impossible de savoir lequel a résolu.
- Ignorer le type d'erreur et chercher directement la "solution Stack Overflow".
- Supprimer l'erreur avec un try/catch vide au lieu de traiter la cause.
Pièges fréquents :
- Works on my machine : vérifier les variables d'environnement, versions, données de test.
- Intermittent bug : penser ordre d'initialisation, état partagé, timeouts.
- Après un déploiement : vérifier la migration DB, les secrets, les dépendances mises à jour.
- Bug en prod seulement : vérifier les logs de prod, les permissions, le volume de données.
Commandes de diagnostic utiles (copiables)
# Git — trouver le commit qui a introduit le bug
git bisect start
git bisect bad HEAD
git bisect good <commit-ok>
# Node.js — lancer avec inspect
node --inspect-brk index.js
# Docker — logs du container
docker logs --tail=100 -f <container>
# Linux — tracer les appels système
strace -p <pid> 2>&1 | grep -v ENOENT
# .NET — heap dump
dotnet-dump collect -p <pid>
Critères de décision — quand escalader
- Le bug est dans une dépendance externe non patchée → ouvrir une issue upstream + workaround temporaire.
- La reproduction nécessite des données de production → demander un dump anonymisé ou un jeu de test équivalent.
- Le fix implique une refonte architecturale → documenter en ADR, ne pas patcher à la va-vite.
- L'erreur est liée à la sécurité (injection, overflow) → traiter comme incident, pas comme bug ordinaire.
Communication Rules — MANDATORY
- Ultra-concise. No filler, no preamble, no pleasantries.
- Never say "happy to help", "sure!", "great question", "let me", or similar.
- Tool first, talk second. Act before explaining.
- Result first. Lead with outcome, not process.
- Stop when done. No summary, no recap, no trailing commentary.
- No politeness wrappers. Direct and blunt.
- Minimum words. If one word works, do not use ten.
- No unsolicited explanations.
- No emoji unless asked.
1---2name: dev-bug-debugger3description: Aide à diagnostiquer et résoudre un bug en suivant une méthodologie structurée. À utiliser quand l'utilisateur a une erreur, un comportement inattendu ou un crash. Se déclenche aussi avec "j'ai un bug", "ça ne marche pas", "erreur", "crash", "pourquoi ça fait ça", "TypeError", "undefined", ou tout message d'erreur collé. Also triggers on "debug this", "why does this fail", "find the root cause", "fix this bug".4---56# Bug Debugger78## Étape 0 — Collecter le contexte minimal910Avant toute hypothèse, s'assurer d'avoir :1112| Info | Exemples |13|---|---|14| Message d'erreur complet | stack trace, code HTTP, errno |15| Comportement attendu vs observé | "devrait retourner 200, retourne 500" |16| Reproductibilité | toujours / parfois / en prod seulement |17| Dernière modification | commit, déploiement, changement config |18| Environnement | OS, version runtime, variables d'env |1920Si un de ces éléments manque et bloque le diagnostic → demander uniquement ce qui est nécessaire, pas tout à la fois.2122---2324## Étape 1 — Lire l'erreur sans sauter aux conclusions2526```27TypeError: Cannot read properties of undefined (reading 'id')28 at getUserName (user.js:42:18)29 at processRequest (api.js:17:5)30```3132- **Lire le type d'erreur** : `TypeError`, `NullReferenceException`, `SIGSEGV`…33- **Localiser le premier frame applicatif** (ignorer les frames de libs tierces).34- **Identifier l'opération qui échoue** : accès propriété, appel fonction, cast, IO…3536---3738## Étape 2 — Formuler 3 hypothèses classées par probabilité3940Format attendu :41421. **(Probable)** `user` est `undefined` car la DB ne retourne rien pour cet ID → vérifier avec `console.log(user)` avant la ligne 42.432. **(Possible)** La fonction est appelée avant que la promesse soit résolue → ajouter `await`.443. **(Moins probable)** Race condition sur un cache partagé → vérifier si ça arrive en parallèle.4546Règle : ne pas proposer plus de 3 hypothèses sans validation intermédiaire.4748---4950## Étape 3 — Vérification rapide par hypothèse5152### JavaScript/TypeScript53```ts54// Inspecter sans modifier le flux55console.log('[debug] user:', JSON.stringify(user, null, 2));56// Vérifier le type exact57console.log('[debug] typeof user:', typeof user, user instanceof Object);58```5960### Python61```python62import pprint63print('[debug] user:', pprint.pformat(user))64# Ou avec breakpoint natif (Python 3.7+)65breakpoint()66```6768### .NET / C#69```csharp70// Ajouter un point de log avant la ligne incriminée71_logger.LogDebug("user={User}", JsonSerializer.Serialize(user));72// Ou utiliser le debugger avec Watch sur l'expression73```7475### Shell / CLI76```bash77# Activer le mode verbose78set -x # bash : affiche chaque commande avant exécution79export DEBUG=* # Node.js : active les logs de debug des modules80```8182---8384## Étape 4 — Correction8586Toujours présenter un diff avant/après :8788```ts89// AVANT90const name = user.profile.name;9192// APRÈS — avec guard null93const name = user?.profile?.name ?? 'Inconnu';94```9596Expliquer **pourquoi** la correction fonctionne, pas seulement **quoi** changer.9798---99100## Étape 5 — Prévention101102Adapter selon le contexte :103104| Type de bug | Prévention recommandée |105|---|---|106| Null/undefined | TypeScript strict, optional chaining, guards |107| Race condition | mutex, transactions, idempotence |108| Régression | test unitaire couvrant le cas exact |109| Config manquante | validation au démarrage (`zod`, `pydantic`) |110| Erreur silencieuse | logger sur les catch, ne jamais `catch {}` vide |111112---113114## Garde-fous et anti-patterns115116**Ne pas faire :**117- Modifier le code sans reproduire le bug d'abord → on peut "corriger" la mauvaise chose.118- Ajouter plusieurs changements à la fois → impossible de savoir lequel a résolu.119- Ignorer le type d'erreur et chercher directement la "solution Stack Overflow".120- Supprimer l'erreur avec un try/catch vide au lieu de traiter la cause.121122**Pièges fréquents :**123- *Works on my machine* : vérifier les variables d'environnement, versions, données de test.124- *Intermittent bug* : penser ordre d'initialisation, état partagé, timeouts.125- *Après un déploiement* : vérifier la migration DB, les secrets, les dépendances mises à jour.126- *Bug en prod seulement* : vérifier les logs de prod, les permissions, le volume de données.127128---129130## Commandes de diagnostic utiles (copiables)131132```bash133# Git — trouver le commit qui a introduit le bug134git bisect start135git bisect bad HEAD136git bisect good <commit-ok>137138# Node.js — lancer avec inspect139node --inspect-brk index.js140141# Docker — logs du container142docker logs --tail=100 -f <container>143144# Linux — tracer les appels système145strace -p <pid> 2>&1 | grep -v ENOENT146147# .NET — heap dump148dotnet-dump collect -p <pid>149```150151---152153## Critères de décision — quand escalader154155- Le bug est dans une dépendance externe non patchée → ouvrir une issue upstream + workaround temporaire.156- La reproduction nécessite des données de production → demander un dump anonymisé ou un jeu de test équivalent.157- Le fix implique une refonte architecturale → documenter en ADR, ne pas patcher à la va-vite.158- L'erreur est liée à la sécurité (injection, overflow) → traiter comme incident, pas comme bug ordinaire.159160161## Communication Rules — MANDATORY162163- Ultra-concise. No filler, no preamble, no pleasantries.164- Never say "happy to help", "sure!", "great question", "let me", or similar.165- Tool first, talk second. Act before explaining.166- Result first. Lead with outcome, not process.167- Stop when done. No summary, no recap, no trailing commentary.168- No politeness wrappers. Direct and blunt.169- Minimum words. If one word works, do not use ten.170- No unsolicited explanations.171- No emoji unless asked.