Les hooks de Claude Code ne fonctionnent pas sous Windows : causes et solutions

Le même hook qui fonctionne parfaitement sur Mac ne fait rien sous Windows, ou pire, bloque toutes les commandes. Presque toujours, c’est le shell. Voici comment Claude Code exécute les hooks sous Windows et comment rendre les vôtres fiables.

Par Aslan, équipe Pet Island · Mis à jour le 26 oct. 2026 · 5 min de lecture

RÉPONSE COURTE

Sous Windows, Claude Code exécute la command d’un hook avec Git Bash, ou avec PowerShell si Git Bash n’est pas installé. Indiquez celui que vous voulez avec "shell": "powershell" ou "shell": "bash", limitez stdout à un seul objet JSON (aucun echo du profil), utilisez le code de sortie 2 pour bloquer et mettez Claude Code à jour (plusieurs bugs de hooks sous Windows ont été corrigés dans les versions jusqu’à 2.1.310). Déboguez avec /hooks et claude --debug.

Quel shell exécute votre hook

Claude Code transmet la chaîne command à un shell : sh -c sous macOS et Linux, Git Bash sous Windows, ou PowerShell si Git Bash n’est pas installé. Cette seule phrase de la référence des hooks explique la plupart des signalements du type « ça marche sur mon Mac ». Une commande écrite pour PowerShell échoue dans Git Bash, un script bash échoue dans PowerShell, et celui que vous obtenez dépend du fait que Git for Windows soit installé ou non.

Éliminez l’incertitude avec le champ shell. Il accepte "bash" ou "powershell" :

%USERPROFILE%\.claude\settings.jsonCopier
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"shell": "powershell",
"command": "[Console]::Beep(880, 200)"
}
]
}
]
}
}

Si vous voulez Git Bash et que Claude Code ne le trouve pas, installez Git for Windows ou définissez CLAUDE_CODE_GIT_BASH_PATH sur son emplacement, puis démarrez une nouvelle session.

Les symptômes et leurs causes

Ce que vous constatezCause probableSolution
Le hook ne semble jamais s’exécuterAncienne version de Claude Code, mauvais événement ou mauvais matcher, JSON invalide dans les paramètresMettez à jour ; vérifiez /hooks ; supprimez les commentaires et les virgules finales
ParserError ou « unexpected token »De la syntaxe PowerShell qui arrive dans Git Bash, ou l’inverseDéfinissez shell explicitement
Sortie du hook « does not start with { »Quelque chose a été affiché avant le JSON, souvent par un profil de shellRendez le profil silencieux ; envoyez les journaux vers stderr
Un chemin mêlant \ et / est introuvableUne variable de chemin Windows concaténée avec un suffixe de style UnixUtilisez la forme exec : le programme dans command, chaque argument dans args
powershell: Permission denied depuis Git BashSignalé de façon intermittente dans 2.1.283 et 2.1.304–2.1.305 (#103910, ouverte)Utilisez "shell": "powershell" pour que Git Bash ne soit pas intercalé
Un hook de garde laisse tout passerCode de sortie 1 au lieu de 2, ou bug d’ouverture en cas d’échec (fail-open) dans les anciennes versionsSortez avec le code 2 pour bloquer ; passez à 2.1.310 ou version ultérieure
Le hook rend la main immédiatement sans aucune sortieUn programme du sous-système graphique que le shell n’attend pasUtilisez un programme console, ou attendez la fin du processus

Uniquement du JSON sur stdout

Claude Code lit la sortie standard de votre hook comme sa réponse. La règle de la documentation est simple : n’écrivez rien d’autre que l’objet JSON sur stdout. Sous Windows, cela casse de façon sournoise : Git Bash et certaines configurations chargent quand même votre profil de shell, et un echo inconditionnel dans ce profil se retrouve ajouté devant votre JSON. Le hook « fonctionne » alors dans un terminal et échoue dans Claude Code.

Écrivez plutôt vos journaux dans un fichier ou sur stderr, et n’affichez la sortie de votre profil que dans un shell interactif.

Codes de sortie : 2 bloque, 1 ne bloque pas

Le code de sortie 0 signifie la réussite. Le code 2 est une erreur bloquante : pour les événements qui peuvent être bloqués, Claude Code arrête l’action et affiche votre stderr. Le code 1 sans JSON valide est une erreur non bloquante, et l’action se poursuit. Si votre hook applique une stratégie, utilisez le code 2.

Tous les événements ne peuvent pas être bloqués de cette façon. Le code de sortie d’un hook Notification est ignoré. Un hook Stop qui sort avec le code 2 fait continuer Claude. Un hook PermissionRequest ignore complètement le code 2 : il décide via un objet decision dans son JSON.

Claude Code 2.1.309 a corrigé les hooks PowerShell qui ne bloquaient pas quand le programme du hook sortait avec le code 2. Si votre garde PowerShell semble ignorée, vérifiez d’abord votre version.

Les correctifs Windows qui justifient une mise à jour

Le changelog d’Anthropic contient une longue série de correctifs de hooks sous Windows. Voici ceux qui expliquent d’anciens fils de forum :

VersionCorrectif
2.1.47Les hooks PreToolUse et PostToolUse échouaient silencieusement sous Windows ; ils s’exécutent désormais avec Git Bash au lieu de cmd.exe
2.1.161Les hooks qui appellent bash explicitement (/usr/bin/bash script.sh) échouaient avec « command not found »
2.1.299Les hooks PreToolUse et PermissionRequest sans shell défini laissaient tout passer en cas d’échec sans Git for Windows ; une garde en échec bloque désormais
2.1.309Les hooks PowerShell ne bloquaient pas avec le code de sortie 2 ; les gardes "shell": "powershell" laissaient tout passer sans Git for Windows
2.1.310Les gardes dont la commande n’était composée que de chaînes entre guillemets (comme un chemin entre guillemets) laissaient tout passer sans Git Bash

L’ancienne issue intitulée « No hook is working on Windows » (#10450) a été signalée sur la 2.0.27 ; un commentateur l’a attribuée à stdin qui n’atteignait pas les commandes des hooks. Si vous utilisez une version aussi ancienne, mettez à jour avant de déboguer quoi que ce soit d’autre.

Appeler un programme directement

Si votre hook est un programme compilé, vous pouvez vous passer du shell avec la forme exec (le champ args ; shell est ignoré quand args est défini). Sous Windows, la forme exec exige que command corresponde à un véritable exécutable, comme un .exe ; les shims .cmd et .bat (dont la plupart des éléments installés par npm) ne peuvent pas être lancés sans shell. Pointez vers le .exe, ou utilisez la forme shell.

Une leçon tirée du développement de notre propre utilitaire de hook : sous Windows, un programme compilé pour le sous-système graphique n’est pas attendu quand un shell le lance. Le shell rend la main aussitôt, l’agent lit une sortie vide, et le hook semble mort. Les programmes de hook doivent être des programmes console.

Hooks de plugins et chemins

Les hooks de plugins qui construisent des chemins comme ${CLAUDE_PLUGIN_ROOT}/hooks/run.sh ne fonctionnaient plus sous Windows entre la v2.1.2 et la v2.1.12 (#18610) : la variable se développe en un chemin avec des barres obliques inverses, et l’ajout d’un suffixe avec des barres obliques donne un chemin mixte que bash ne sait pas résoudre. La documentation actuelle donne la solution propre : utilisez la forme exec chaque fois qu’un hook fait référence à un espace réservé de chemin. Placez le programme dans command et chaque argument dans args, par exemple "command": "node", "args": ["${CLAUDE_PLUGIN_ROOT}/scripts/format.js"]. Chaque élément est transmis comme un seul argument, sans shell pour le déformer.

Liste de vérification pour le débogage

  1. /hooks ouvre une liste en lecture seule de tous les hooks configurés et de leur provenance.
  2. claude --debug (ou /debug en cours de session) affiche chaque exécution de hook, sa sortie et son code de sortie. claude --debug-file <path> l’écrit dans un fichier.
  3. Validez le JSON. Les fichiers de paramètres sont du JSON strict ; une seule virgule finale désactive tout le fichier.
  4. Vérifiez le matcher. Les matchers sont sensibles à la casse ; "*", "" ou l’absence de matcher correspondent à tout.
  5. Exécutez la commande vous-même dans le shell que Claude Code utilisera, en lui envoyant un exemple de JSON par un pipe.
  6. Vérifiez le délai d’expiration. Les hooks de commande ont un délai par défaut de 600 secondes ; un hook qui attend une personne a besoin de cette marge.

Pour désactiver tous les hooks pendant votre investigation, définissez "disableAllHooks": true.

Si vous vouliez seulement des notifications et des approbations

Beaucoup de configurations de hooks sous Windows n’existent que pour une raison : savoir quand Claude Code a besoin de vous et lui répondre. Pet Island le fait sans aucun script. Il se connecte à Claude Code en un clic, gère les détails propres à Windows à votre place et affiche chaque demande d’autorisation, chaque question et chaque plan sur une petite île en haut de l’écran, avec la commande ou le diff, où vous les autorisez ou les refusez. Il fonctionne aussi quand Claude Code s’exécute dans WSL.

FAQ

Quel shell exécute les hooks de Claude Code sous Windows ?

Git Bash, ou PowerShell si Git Bash n’est pas installé. Définissez "shell": "powershell" ou "shell": "bash" dans le hook pour choisir explicitement.

Pourquoi mon hook Claude Code fonctionne-t-il dans le terminal mais pas dans Claude Code ?

En général à cause d’une sortie en trop : un profil de shell qui affiche du texte se retrouve devant le JSON du hook. N’écrivez que l’objet JSON sur stdout.

Comment faire en sorte qu’un hook bloque un appel d’outil ?

Sortez avec le code 2 (ou renvoyez une décision deny en JSON). Le code de sortie 1 est une erreur non bloquante et l’action se poursuit. Les hooks PermissionRequest ignorent le code 2 et utilisent un objet decision à la place.

La commande d’un hook peut-elle être un fichier .cmd ou .bat ?

Pas en forme exec. Sous Windows, elle doit correspondre à un véritable exécutable, comme un .exe. Utilisez la forme shell pour exécuter des fichiers .cmd ou .bat.

Comment savoir pourquoi un hook a échoué ?

Lancez claude --debug ou tapez /debug, et utilisez /hooks pour voir quels hooks sont chargés.

Sources

Chaque paramètre et chaque comportement décrits sur cette page ont été vérifiés dans ces pages le 26 octobre 2026. Les agents évoluent vite : si quelque chose ne correspond plus, c’est la page officielle qui fait foi.

À LIRE AUSSI

Répondez à tous vos agents depuis le haut de votre écran.

Windows et Mac · 7 jours gratuits, puis 8,99 $ une seule fois · 1 $ de chaque vente nourrit des animaux errants

Essayer Pet Island gratuitement