476| `async` | non | Si `true`, s'exécute en arrière-plan sans bloquer. Consultez [Exécuter les hooks en arrière-plan](#run-hooks-in-the-background) |476| `async` | non | Si `true`, s'exécute en arrière-plan sans bloquer. Consultez [Exécuter les hooks en arrière-plan](#run-hooks-in-the-background) |
477| `asyncRewake` | non | Si `true`, s'exécute en arrière-plan et réveille Claude au code de sortie 2. Le stderr du hook, ou stdout s'il est vide, est affiché à Claude comme un [rappel système](/docs/fr/glossary#system-reminder) afin qu'il puisse réagir à un échec en arrière-plan de longue durée |477| `asyncRewake` | non | Si `true`, s'exécute en arrière-plan et réveille Claude au code de sortie 2. Le stderr du hook, ou stdout s'il est vide, est affiché à Claude comme un [rappel système](/docs/fr/glossary#system-reminder) afin qu'il puisse réagir à un échec en arrière-plan de longue durée |
478| `shell` | non | Shell à utiliser pour ce hook. Accepte `"bash"` ou `"powershell"`. Par défaut `"bash"`, ou `"powershell"` sur Windows lorsque Git Bash n'est pas installé. Définir `"powershell"` exécute la commande via PowerShell sur Windows. Ne nécessite pas `CLAUDE_CODE_USE_POWERSHELL_TOOL` puisque les hooks lancent PowerShell directement. Ignoré lorsque `args` est défini |478| `shell` | non | Shell à utiliser pour ce hook. Accepte `"bash"` ou `"powershell"`. Par défaut `"bash"`, ou `"powershell"` sur Windows lorsque Git Bash n'est pas installé. Définir `"powershell"` exécute la commande via PowerShell sur Windows. Ne nécessite pas `CLAUDE_CODE_USE_POWERSHELL_TOOL` puisque les hooks lancent PowerShell directement. Ignoré lorsque `args` est défini |
479| `onFailure` | non | Ce qu'il advient de l'action lorsque le hook échoue : `"continue"`, la valeur par défaut, ou `"block"`. Consultez [Bloquer l'action lorsqu'un hook échoue](#block-the-action-when-a-hook-fails). Nécessite Claude Code v2.1.295 ou ultérieur |
479 480
480<a id="exec-form-and-shell-form" />481<a id="exec-form-and-shell-form" />
481 482
533| `url` | oui | URL vers laquelle envoyer la requête POST |534| `url` | oui | URL vers laquelle envoyer la requête POST |
534| `headers` | non | En-têtes HTTP supplémentaires sous forme de paires clé-valeur. Les valeurs supportent l'interpolation de variables d'environnement en utilisant la syntaxe `$VAR_NAME` ou `${VAR_NAME}`. Seules les variables listées dans `allowedEnvVars` sont résolues |535| `headers` | non | En-têtes HTTP supplémentaires sous forme de paires clé-valeur. Les valeurs supportent l'interpolation de variables d'environnement en utilisant la syntaxe `$VAR_NAME` ou `${VAR_NAME}`. Seules les variables listées dans `allowedEnvVars` sont résolues |
535| `allowedEnvVars` | non | Liste des noms de variables d'environnement qui peuvent être interpolés dans les valeurs d'en-tête. Les références aux variables non listées sont remplacées par des chaînes vides. Requis pour que l'interpolation de variables d'environnement fonctionne |536| `allowedEnvVars` | non | Liste des noms de variables d'environnement qui peuvent être interpolés dans les valeurs d'en-tête. Les références aux variables non listées sont remplacées par des chaînes vides. Requis pour que l'interpolation de variables d'environnement fonctionne |
537| `onFailure` | non | Ce qu'il advient de l'action lorsque le hook échoue : `"continue"`, la valeur par défaut, ou `"block"`. Consultez [Bloquer l'action lorsqu'un hook échoue](#block-the-action-when-a-hook-fails). Nécessite Claude Code v2.1.295 ou ultérieur |
536 538
537Claude Code envoie l'[entrée JSON](#hook-input-and-output) du hook en tant que corps de la requête POST avec `Content-Type: application/json`. Le corps de la réponse utilise le même [format de sortie JSON](#json-output) que les hooks de commande.539Claude Code envoie l'[entrée JSON](#hook-input-and-output) du hook en tant que corps de la requête POST avec `Content-Type: application/json`. Le corps de la réponse utilise le même [format de sortie JSON](#json-output) que les hooks de commande.
538 540
821 Sortie du code de sortie823 Sortie du code de sortie
822</h3>824</h3>
823 825
824Le code de sortie de votre commande de hook indique à Claude Code si l'action doit procéder, être bloquée ou être ignorée. Le code de sortie n'agit pas seul. Claude Code lit les [champs de sortie JSON](#json-output) depuis stdout sur chaque code de sortie, pas seulement 0, et pour les événements qui utilisent le modèle de décision standard, un objet analysé qui passe la validation du schéma prend effet aux côtés du code. Le blocage d'exit 2 est le seul résultat que JSON ne peut pas remplacer.826Le code de sortie de votre hook indique à Claude Code s'il doit poursuivre l'action qui a déclenché le hook, comme un appel d'outil ou un prompt. Une exécution qui se termine aboutit à l'un de ces trois résultats :
825 827
826Deux tableaux possèdent les exceptions par événement : [Comportement du code de sortie 2 par événement](#exit-code-2-behavior-per-event) dit ce que les codes de sortie font pour chaque événement, et [Contrôle de décision](#decision-control) dit quels champs de décision chaque événement honore. Les champs universels tels que `systemMessage` fonctionnent sur la plupart des événements et sont listés dans le tableau [Sortie JSON](#json-output).828* **Succès** : votre hook quitte avec 0. Claude Code applique tous les champs de [sortie JSON](#json-output) que votre hook a imprimés, et l'action se poursuit sauf si ces champs la bloquent ou la refusent.
829* **Erreur bloquante** : votre hook quitte avec 2. Sur [les événements qui peuvent bloquer](#exit-code-2-behavior-per-event), Claude Code arrête l'action.
830* **Erreur non-bloquante** : votre hook quitte avec tout autre code, ou échoue d'une autre manière, par exemple en ne démarrant pas ou en imprimant du JSON invalide. L'action se poursuit, et sur des événements tels que `PreToolUse`, vous voyez un avis `<hook name> hook error` dans la transcription. Si vous souhaitez qu'un hook en échec bloque l'action, définissez [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
831
832Ce que votre hook imprime sur stdout peut changer le résultat. Par exemple, si un hook `PreToolUse` quitte avec 1 mais imprime du JSON qui passe la validation, l'exécution est un succès et les champs JSON décident de ce qui se passe. Pour trouver le résultat de votre hook sur un événement tel que `PreToolUse`, faites correspondre ce qu'il a imprimé sur stdout dans la première colonne avec son code de sortie en haut :
833
834| Stdout | Exit 0 | Exit 2 | Tout autre code de sortie |
835| :- | :- | :- | :- |
836| Objet JSON qui passe la [validation du schéma](#json-output) | Succès. Les champs s'appliquent | Erreur bloquante. Claude Code lit toujours les champs, mais ils ne peuvent pas remplacer le blocage | Succès. Claude Code ignore le code de sortie, et les champs seuls décident. Avec [`onFailure: "block"`](#block-the-action-when-a-hook-fails), cela compte comme un échec |
837| JSON qui [ne peut pas être analysé](#exit-code-0) ou échoue la validation du schéma | Erreur non-bloquante. L'avis porte le message d'analyse ou de validation | Erreur bloquante. Votre stderr est la raison | Erreur non-bloquante. L'avis porte le message d'analyse ou de validation |
838| [Texte brut](#exit-code-0), ou rien | Succès | Erreur bloquante. Votre stderr est la raison | Erreur non-bloquante. L'avis porte la première ligne de votre stderr |
839
840Certains événements ont leurs propres règles :
841
842* **`WorktreeCreate`** : tout code de sortie non-zéro fait échouer la création du worktree, quoi que dise votre JSON.
843* **`WorktreeRemove`** : tout code de sortie non-zéro fait échouer la suppression du worktree si le répertoire existe toujours après.
844* **`Stop`, `SubagentStop`, `TaskCompleted` et le hook `UserPromptSubmit` d'un plugin** : lorsque votre hook quitte avec 2 sans rien sur stdout et que son stderr indique qu'un fichier est manquant, comme `No such file or directory`, Claude Code traite l'exécution comme une erreur non-bloquante.
845* **`Elicitation` et `ElicitationResult`** : Claude Code applique votre `hookSpecificOutput` lorsque votre hook quitte avec 0, et l'ignore sur tout autre code de sortie.
846* **Les événements qui rejettent la sortie du hook, comme `StopFailure`** : Claude Code ignore votre JSON sur chaque code de sortie, à part les champs d'effet secondaire comme `terminalSequence`, qui se déclenchent toujours.
847
848Pour vérifier ce que fait le code de sortie 2 sur votre événement, consultez [Comportement du code de sortie 2 par événement](#exit-code-2-behavior-per-event). Pour vérifier quels champs de décision il honore, consultez [Contrôle de décision](#decision-control).
827 849
828<h4 id="exit-code-0">850<h4 id="exit-code-0">
829 Exit code 0851 Exit code 0
835 857
836Que Claude Code lise votre stdout comme [sortie JSON](#json-output) ou comme texte brut dépend de la façon dont il commence et se termine, en ignorant les espaces blancs environnants :858Que Claude Code lise votre stdout comme [sortie JSON](#json-output) ou comme texte brut dépend de la façon dont il commence et se termine, en ignorant les espaces blancs environnants :
837 859
838* **Commence par `{` et se termine par `}`** : Claude Code l'analyse comme JSON. Lorsque la sortie est deux lignes ou plus qui s'analysent chacune comme JSON seules, et aucune ligne n'est un objet [sortie JSON](#json-output) qui définit un champ, Claude Code traite la sortie entière comme du texte brut. Lorsque l'une de ces lignes définit un champ, la sortie entière est un échec d'analyse, décrit ci-dessous.860* **Commence par `{` et se termine par `}`** : Claude Code l'analyse comme JSON. Lorsque la sortie est deux lignes ou plus qui s'analysent chacune comme JSON seules, et aucune ligne n'est un objet [sortie JSON](#json-output) qui définit un champ, Claude Code traite la sortie entière comme du texte brut. Lorsque l'une de ces lignes définit un champ, la sortie entière est un échec d'analyse.
839* **Commence par `{` mais ne se termine pas par `}`** : Claude Code le traite comme du texte brut.861* **Commence par `{` mais ne se termine pas par `}`** : Claude Code le traite comme du texte brut.
840* **Commence par n'importe quoi d'autre** : Claude Code le traite comme du texte brut, y compris s'il s'agit d'un tableau JSON ou d'une chaîne JSON entre guillemets.862* **Commence par n'importe quoi d'autre** : Claude Code le traite comme du texte brut, y compris s'il s'agit d'un tableau JSON ou d'une chaîne JSON entre guillemets.
841 863
842Pour les événements qui utilisent le modèle de décision standard, exit 0 avec un objet analysé qui échoue la validation du schéma est une erreur non-bloquante : l'action procède, et la transcription affiche un avis `<hook name> hook error` avec le message de validation. La même chose se produit sur tout code de sortie autre que 2, tandis que [exit 2 bloque toujours](#exit-code-2).864Lorsque Claude Code essaie d'analyser votre stdout comme JSON et ne peut pas, ou que l'objet analysé échoue la [validation du schéma](#json-output), l'exécution est une [erreur non-bloquante](#exit-code-output). L'avis `<hook name> hook error` porte le message d'analyse ou de validation. Sur les événements qui ajoutent stdout en texte brut comme contexte, Claude Code n'ajoute pas le stdout qu'il n'a pas pu analyser.
843
844Pour les événements qui utilisent le modèle de décision standard, lorsque Claude Code essaie d'analyser votre stdout comme JSON et ne peut pas, il rapporte une erreur non-bloquante sur chaque code de sortie autre que 2. La transcription affiche un avis `<hook name> hook error` avec le message d'analyse. Sur les événements qui ajoutent stdout en texte brut comme contexte, Claude Code n'ajoute pas le texte. Avant v2.1.248, Claude Code traitait ce stdout comme du texte brut.
845 865
846Stderr d'un hook qui quitte 0 va uniquement au journal de débogage, jamais à la transcription, et Claude ne le voit jamais. Pour le lire vous-même, activez [la journalisation de débogage](#debug-hooks). Pour afficher un avertissement à Claude à partir d'un hook `PostToolUse` ou `PostToolUseFailure`, quittez 2 à la place afin que [Claude voie stderr](#exit-code-2-behavior-per-event) même si l'outil s'est déjà exécuté.866Claude ne voit jamais le stderr d'un hook qui quitte avec 0. Pour le lire vous-même sur des événements tels que `PreToolUse`, activez [la journalisation de débogage](#debug-hooks). Pour afficher un avertissement à Claude à partir d'un hook `PostToolUse` ou `PostToolUseFailure`, quittez 2 à la place afin que [Claude voie stderr](#exit-code-2-behavior-per-event) même si l'outil s'est déjà exécuté.
847 867
848<h4 id="exit-code-2">868<h4 id="exit-code-2">
849 Exit code 2869 Exit code 2
850</h4>870</h4>
851 871
852Exit 2 signifie une erreur bloquante. Sur [les événements qui peuvent bloquer](#exit-code-2-behavior-per-event), exit 2 bloque que vous imprimiez JSON ou non : même une `permissionDecision` JSON de `"allow"` ne peut pas la remplacer. Claude Code lit toujours toute [sortie JSON](#json-output) valide sur stdout. Sur `Elicitation` et `ElicitationResult`, le `hookSpecificOutput` d'un hook exit-2 est ignoré.872Quittez avec le code 2 pour bloquer l'action. Sur [les événements qui peuvent bloquer](#exit-code-2-behavior-per-event), Claude Code arrête l'action : un hook `PreToolUse` bloque l'appel d'outil, par exemple, et un hook `UserPromptSubmit` rejette le prompt.
853 873
854Le message de blocage est la raison de la décision de blocage de votre JSON lorsqu'elle en fait une, et votre texte stderr sinon. Ce que le blocage fait varie selon l'événement : `PreToolUse` bloque l'appel d'outil, `UserPromptSubmit` rejette le prompt, et ainsi de suite. [Comportement du code de sortie 2 par événement](#exit-code-2-behavior-per-event) énumère l'effet pour chaque événement, et chaque section d'événement dit où le message va.874Le message qui accompagne le blocage est le stderr de votre hook. Si votre hook a également imprimé du JSON qui prend une décision de blocage, Claude Code utilise la raison de cette décision à la place.
855 875
856Un hook qui quitte 2 tout en imprimant JSON qui échoue la validation du schéma [sortie JSON](#json-output) bloque toujours : Claude Code utilise stderr comme raison de blocage et consigne l'échec de validation dans le journal de débogage. Avant v2.1.214, Claude Code traitait cette combinaison comme une erreur non-bloquante et l'action procédait.876Exit 2 bloque même lorsque votre hook imprime du JSON :
877
878* **JSON qui passe la validation du schéma** : Claude Code lit toujours les champs de [sortie JSON](#json-output), mais ils ne peuvent pas remplacer le blocage. Même une `permissionDecision` de `"allow"` ne laisse pas passer l'action. Sur `Elicitation` et `ElicitationResult`, le `hookSpecificOutput` d'un hook exit-2 est ignoré.
879* **JSON qui échoue la validation du schéma** : le hook bloque toujours. Claude Code utilise votre stderr comme raison de blocage et consigne l'échec de validation dans le journal de débogage.
857 880
858Ce script bloque les commandes `rm` en quittant 2 et laisse chaque autre commande au flux de permission normal :881Ce script bloque les commandes `rm` en quittant 2 et laisse chaque autre commande au flux de permission normal :
859 882
871exit 0 # Pas de décision : le flux de permission normal s'applique894exit 0 # Pas de décision : le flux de permission normal s'applique
872```895```
873 896
897Avec ce script enregistré comme hook `PreToolUse` sur `Bash`, une commande qui commence par `rm` est bloquée, et Claude reçoit le stderr du hook comme erreur de l'outil, préfixé par le nom de l'événement, le nom de l'outil et la commande du hook :
898
899```text theme={null}
900PreToolUse:Bash hook error: [${CLAUDE_PROJECT_DIR}/.claude/hooks/no-rm.sh]: Blocked: rm commands are not allowed
901```
902
874<h4 id="other-exit-codes">903<h4 id="other-exit-codes">
875 Autres codes de sortie904 Autres codes de sortie
876</h4>905</h4>
877 906
878Tout autre code de sortie ne bloque pas seul pour la plupart des événements de hook. Ce qui se passe dépend de votre stdout :907Lorsque votre hook quitte avec un code autre que 0 ou 2 et imprime du texte brut ou rien sur stdout, l'exécution est une [erreur non-bloquante](#exit-code-output). Vous voyez un avis `<hook name> hook error` dans la transcription avec `Failed with non-blocking status code:` et la première ligne du stderr de votre hook. Par exemple, lorsqu'un hook `PreToolUse` sur `Bash` imprime `something broke` sur stderr et quitte avec 1, l'avis `PreToolUse:Bash hook error` porte cette ligne :
879 908
880* Avec un objet analysé qui passe la validation du schéma, pour les événements qui utilisent le modèle de décision standard, Claude Code ignore le code de sortie et le JSON seul décide du résultat :909```text theme={null}
881 * Chaque champ que l'événement supporte est honoré, y compris `permissionDecision`, `additionalContext`, `updatedInput` et `systemMessage`, et le hook n'est pas signalé comme une erreur.910Failed with non-blocking status code: something broke
882 * [Contrôle de décision](#decision-control) énumère les champs de décision par événement ; les champs universels comme `systemMessage` suivent le tableau [Sortie JSON](#json-output).911```
883* Avec un objet analysé qui échoue la validation du schéma, pour les événements qui utilisent le modèle de décision standard, c'est la même erreur non-bloquante que [sur exit 0](#exit-code-0) : l'action procède, et l'avis `<hook name> hook error` porte le message de validation.
884* Avec stdout que Claude Code [essaie d'analyser comme JSON](#exit-code-0) et ne peut pas, Claude Code rapporte la même erreur non-bloquante que sur exit 0 pour les événements qui utilisent le modèle de décision standard. L'action procède, et l'avis porte le message d'analyse.
885* Avec stdout que Claude Code [traite comme du texte brut](#exit-code-0), ou avec stdout vide, c'est une erreur non-bloquante pour la plupart des événements de hook : l'action procède, et la transcription affiche un avis `<hook name> hook error` suivi de la première ligne de stderr, préfixée par `Failed with non-blocking status code:`. Pour capturer le stderr complet, activez [la journalisation de débogage](#debug-hooks).
886 912
887Les événements en dehors du modèle de décision standard gardent leurs propres lignes dans le [tableau par événement](#exit-code-2-behavior-per-event) : `WorktreeCreate` fait échouer la création sur tout code de sortie non-zéro peu importe ce que votre JSON dit, et les événements qui rejettent complètement la sortie du hook, comme `StopFailure`, ignorent votre JSON sur chaque code de sortie, à part les champs d'effet secondaire comme `terminalSequence`, qui se déclenchent toujours.913Pour capturer le stderr complet plutôt que sa première ligne, activez [la journalisation de débogage](#debug-hooks).
888 914
889Un hook qui ne peut pas démarrer atterrit dans la même catégorie non-bloquante. Lorsque le chemin du script n'existe pas ou n'est pas exécutable, le shell quitte avec un code comme 127 et vous voyez le même avis avec le message de l'interpréteur, par exemple `Failed with non-blocking status code: /bin/sh: /path/to/hook.sh: No such file or directory`. Pour la plupart des événements de hook, l'action procède. Lorsque vous configurez un hook de politique, surveillez cet avis à sa première exécution : un chemin mal orthographié dans `settings.json` laisse le contrôle silencieusement désactivé.915Un hook qui ne peut pas démarrer est également une erreur non-bloquante. Sous forme shell, lorsque le chemin du script n'existe pas ou n'est pas exécutable, le shell quitte avec un code comme 127 et l'avis porte le message de l'interpréteur, par exemple `Failed with non-blocking status code: /bin/sh: /path/to/hook.sh: No such file or directory`. Lorsque vous configurez un hook de politique, surveillez cet avis à sa première exécution, car un chemin mal orthographié dans `settings.json` signifie que le hook ne s'exécute jamais. Pour bloquer l'action à la place, définissez [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
890 916
891<Warning>917<Warning>
892 Pour la plupart des événements de hook, exit code 2 est le seul code de sortie qui bloque par le code seul. Sans JSON valide sur stdout, Claude Code traite exit code 1 comme une erreur non-bloquante et procède avec l'action, même si 1 est le code d'échec Unix conventionnel. Si votre hook est destiné à appliquer une politique, utilisez `exit 2`. Les événements worktree diffèrent : tout code de sortie non-zéro de `WorktreeCreate` abandonne la création du worktree, et tout code de sortie non-zéro de `WorktreeRemove` fait échouer la suppression du worktree si le répertoire existe toujours après.918 Sans JSON valide sur stdout, Claude Code traite exit code 1 comme une erreur non-bloquante, même si 1 est le code d'échec Unix conventionnel. Si votre hook est destiné à appliquer une politique, utilisez `exit 2`.
893</Warning>919</Warning>
894 920
895<h4 id="timeouts">921<h4 id="timeouts">
900 926
901Sur [`PreModelSwitch`](#premodelswitch), un hook annulé à son délai d'expiration bloque le changement de modèle. Sur `PreToolUse`, les deux familles de hooks diffèrent :927Sur [`PreModelSwitch`](#premodelswitch), un hook annulé à son délai d'expiration bloque le changement de modèle. Sur `PreToolUse`, les deux familles de hooks diffèrent :
902 928
903* Un hook `command`, `http` ou `mcp_tool` expiré ne bloque pas l'appel d'outil. L'appel continue via le [flux de permission](/docs/fr/permissions) normal, donc ne comptez pas sur un hook bloqué pour agir comme un contrôle.929* Un hook `command`, `http` ou `mcp_tool` expiré ne bloque pas l'appel d'outil. L'appel continue via le [flux de permission](/docs/fr/permissions) normal, donc ne comptez pas sur un hook bloqué pour agir comme un contrôle. Pour bloquer l'appel lorsqu'un hook `command` ou `http` expire, définissez [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
904* Un hook de rappel [Agent SDK](/docs/fr/agent-sdk/hooks) qui dépasse son délai d'expiration [bloque l'appel d'outil](#pretooluse).930* Un hook de rappel [Agent SDK](/docs/fr/agent-sdk/hooks) qui dépasse son délai d'expiration [bloque l'appel d'outil](#pretooluse).
905 931
932<h4 id="block-the-action-when-a-hook-fails">
933 Bloquer l'action lorsqu'un hook échoue
934</h4>
935
936Sur la plupart des événements, lorsqu'un hook échoue ou expire, Claude Code exécute quand même l'action, de sorte qu'un hook de politique avec un chemin erroné ou un script qui plante laisse tout passer. Pour bloquer l'action à la place, définissez `"onFailure": "block"` sur un hook `command` ou `http`. La valeur par défaut est `"continue"`. Nécessite Claude Code v2.1.295 ou ultérieur.
937
938Ce hook `PreToolUse` dans `.claude/settings.json` exécute un script de projet avant chaque commande Bash, et bloque la commande si le script échoue :
939
940```json theme={null}
941{
942 "hooks": {
943 "PreToolUse": [
944 {
945 "matcher": "Bash",
946 "hooks": [
947 {
948 "type": "command",
949 "command": "node",
950 "args": ["${CLAUDE_PROJECT_DIR}/.claude/hooks/check-command.js"],
951 "onFailure": "block"
952 }
953 ]
954 }
955 ]
956 }
957}
958```
959
960Pour le tester, laissez `check-command.js` absent et demandez à Claude d'exécuter une commande Bash telle que `ls`. Claude Code bloque l'appel, et l'erreur inclut `failed; blocking because onFailure is "block"` suivi de la propre sortie d'erreur de node, réduite ici à une ligne :
961
962```text theme={null}
963PreToolUse:Bash hook error: [node ${CLAUDE_PROJECT_DIR}/.claude/hooks/check-command.js]: failed; blocking because onFailure is "block"
964Error: Cannot find module '/path/to/project/.claude/hooks/check-command.js'
965```
966
967Après un délai d'expiration, le message indique `timed out` au lieu de `failed`. Sans `onFailure` défini, le même script manquant est une erreur non-bloquante et `ls` s'exécute.
968
969Chacun de ces cas compte comme un échec :
970
971* **Impossible de démarrer** : un hook de commande ne parvient pas à démarrer, par exemple parce que le script ou l'exécutable n'existe pas
972* **Code de sortie autre que 0 ou 2** : compte pour un hook de commande même s'il a imprimé du JSON qui autorise l'action, comme `permissionDecision: "allow"`. Pour retourner une décision JSON, quittez avec 0
973* **Erreur HTTP** : la connexion d'un hook HTTP échoue, ou le statut de la réponse n'est pas 2xx
974* **Délai d'expiration** : le hook atteint son [`timeout`](#common-fields)
975* **Sortie invalide** : la sortie JSON [ne peut pas être analysée](#exit-code-0) ou échoue la [validation du schéma](#json-output). Pour un hook HTTP, un corps 2xx qui n'est ni vide ni un objet JSON compte également. Le stdout en texte brut d'un hook de commande n'est pas un échec
976
977Avec `"block"` défini, un échec fait ce que [le code de sortie 2 fait sur cet événement](#exit-code-2-behavior-per-event), sauf sur `PermissionRequest`, où il refuse la demande. Par exemple, un échec `PreToolUse` bloque l'appel d'outil et un échec `UserPromptSubmit` bloque le prompt.
978
979Le champ n'a aucun effet sur ces hooks :
980
981* **Hooks `Stop`, `SubagentStop`, `TaskCompleted` et `TeammateIdle`** : le code de sortie 2 sur ces événements renvoie Claude au travail, et Claude ne peut pas réparer un hook qui ne s'exécute pas
982* **Hooks de commande en arrière-plan** : les hooks de commande qui définissent [`async` ou `asyncRewake`](#run-hooks-in-the-background)
983
906<h4 id="exit-code-2-behavior-per-event">984<h4 id="exit-code-2-behavior-per-event">
907 Comportement du code de sortie 2 par événement985 Comportement du code de sortie 2 par événement
908</h4>986</h4>
960* **Défaillance de connexion** : erreur non-bloquante, l'exécution continue1038* **Défaillance de connexion** : erreur non-bloquante, l'exécution continue
961* **Délai d'expiration** : le hook est annulé, comme décrit sous [Délais d'expiration](#timeouts)1039* **Délai d'expiration** : le hook est annulé, comme décrit sous [Délais d'expiration](#timeouts)
962 1040
963Contrairement aux hooks de commande, les hooks HTTP ne peuvent pas signaler une erreur bloquante uniquement via les codes de statut. Pour bloquer un appel d'outil ou refuser une permission, retournez une réponse 2xx avec un corps JSON contenant les champs de décision appropriés.1041Les hooks HTTP ne peuvent pas signaler une erreur bloquante uniquement via le code de statut : un statut non-2xx ou une connexion échouée est une [erreur non-bloquante](#exit-code-output). Pour bloquer un appel d'outil ou refuser une permission, retournez une réponse 2xx avec un corps JSON contenant les champs de décision appropriés. Pour bloquer l'action lorsque la requête échoue ou retourne un statut non-2xx, définissez [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
964 1042
965<h3 id="json-output">1043<h3 id="json-output">
966 Sortie JSON1044 Sortie JSON
1237 Contrôle de décision de SessionStart1315 Contrôle de décision de SessionStart
1238</h4>1316</h4>
1239 1317
1240Claude Code ajoute au contexte de Claude la sortie stdout qu'il [traite comme du texte brut](#exit-code-0). En plus des [champs de sortie JSON](#json-output) disponibles pour tous les hooks, vous pouvez renvoyer ces champs propres à l'événement :1318Un hook SessionStart peut ajouter du contexte pour Claude, fournir le premier message utilisateur, définir le titre de la session, surveiller des fichiers et recharger les skills. Renvoyez le champ correspondant à chacune de ces actions, en plus des [champs de sortie JSON](#json-output) disponibles pour tous les hooks :
1241 1319
1242| Champ | Description |1320| Champ | Description |
1243| :- | :- |1321| :- | :- |
1244| `additionalContext` | Chaîne ajoutée au contexte de Claude au début de la conversation, avant le premier prompt. Consultez [Ajouter du contexte pour Claude](#add-context-for-claude) pour savoir comment le texte est transmis et ce qu'il faut y mettre |1322| `additionalContext` | Chaîne ajoutée au contexte de Claude au début de la conversation, avant le premier prompt. Consultez [Ajouter du contexte pour Claude](#add-context-for-claude) pour savoir comment le texte est transmis et ce qu'il faut y mettre |
1245| `initialUserMessage` | Chaîne utilisée comme premier message utilisateur de la session. S'applique en [mode non interactif](/docs/fr/headless) avec le flag `-p`, où elle devient le premier tour même si aucun prompt n'est fourni. Si un prompt est fourni, il suit comme tour suivant. Contrairement à `additionalContext`, qui se rattache à un tour existant, ce champ crée le tour |1323| `initialUserMessage` | Chaîne utilisée comme premier message utilisateur de la session, en [mode non interactif](/docs/fr/headless) avec le flag `-p`. Elle devient le premier tour même si vous ne passez aucun prompt. Un prompt que vous passez suit comme tour suivant |
1246| `sessionTitle` | Définit le titre de la session, avec le même effet que `/rename`. À utiliser pour nommer automatiquement les sessions à partir du dossier de lancement, de la branche git ou du nom du worktree. S'applique lorsque `source` vaut `"startup"`, `"resume"` ou `"fork"` ; ignoré pour `"clear"` et `"compact"` |1324| `sessionTitle` | Définit le titre de la session, avec le même effet que `/rename`. S'applique lorsque `source` vaut `"startup"`, `"resume"` ou `"fork"` |
1247| `watchPaths` | Tableau de chemins absolus à surveiller pour les événements [FileChanged](#filechanged) pendant cette session |1325| `watchPaths` | Tableau de chemins absolus à surveiller pour les événements [FileChanged](#filechanged) pendant cette session |
1248| `reloadSkills` | Booléen. Lorsqu'il vaut `true`, Claude Code analyse à nouveau les répertoires de [skills](/docs/fr/skills) et de commandes une fois les hooks SessionStart terminés, afin que les skills installés par le hook soient disponibles dans la même session, dès le premier prompt |1326| `reloadSkills` | Booléen. Lorsqu'il vaut `true`, Claude Code analyse de nouveau les répertoires de [skills](/docs/fr/skills) et de commandes une fois les hooks SessionStart terminés. Consultez [Recharger les skills installés par un hook](#reload-skills-that-a-hook-installs) |
1327
1328Cette sortie ajoute du contexte et nomme la session :
1249 1329
1250```json theme={null}1330```json theme={null}
1251{1331{
1257}1337}
1258```1338```
1259 1339
1260Comme la sortie stdout brute parvient déjà à Claude pour cet événement, un hook qui se contente de charger du contexte peut écrire directement sur stdout sans construire de JSON. Utilisez la forme JSON lorsque vous devez combiner le contexte avec d'autres champs comme `sessionTitle`.1340Un hook qui se contente d'ajouter du contexte peut l'afficher sans construire de JSON, car Claude Code ajoute la [sortie stdout en texte brut](#exit-code-0) d'un hook SessionStart au contexte de Claude.
1341
1342Si le hook SessionStart de votre plugin fournit `initialUserMessage` ou `sessionTitle`, installez le plugin avant le démarrage de la session. Claude Code ignore ces deux champs provenant d'un plugin dont l'installation se termine après l'exécution des hooks SessionStart.
1343
1344<h4 id="reload-skills-that-a-hook-installs">
1345 Recharger les skills installés par un hook
1346</h4>
1347
1348Pour rendre les skills installés par un hook SessionStart disponibles dans la même session, renvoyez `reloadSkills`. La découverte des skills s'exécute normalement avant la fin des hooks SessionStart ; sans ce champ, les fichiers qu'un hook écrit dans `~/.claude/skills/` ou `.claude/skills/` peuvent être absents lors de l'exécution du premier prompt.
1261 1349
1262Utilisez `reloadSkills` lorsqu'un hook SessionStart installe ou met à jour des skills. La découverte des skills s'exécute normalement avant la fin des hooks SessionStart ; les fichiers que le hook écrit dans `~/.claude/skills/` ou `.claude/skills/` n'apparaîtraient donc sinon que dans la session suivante. Cet exemple synchronise un dépôt de skills partagé et demande la nouvelle analyse :1350Cet exemple synchronise un dépôt de skills partagé et demande une nouvelle analyse :
1263 1351
1264```bash theme={null}1352```bash theme={null}
1265#!/bin/bash1353#!/bin/bash
1270echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'1358echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'
1271```1359```
1272 1360
1273L'URL du dépôt est un exemple fictif ; remplacez-la par votre propre dépôt de skills. Avec cette URL fictive, le clonage échoue et affiche un message `fatal:` sur stderr. La sortie stderr d'un hook SessionStart qui se termine avec le code 0 est purement informative, donc la demande `reloadSkills` s'applique tout de même.1361L'URL du dépôt est un exemple fictif. Remplacez-la par votre propre dépôt de skills.
1274 1362
1275<h4 id="persist-environment-variables">1363<h4 id="persist-environment-variables">
1276 Conserver les variables d'environnement1364 Conserver les variables d'environnement
1419 1507
1420Les hooks `UserPromptSubmit` ont un délai d'expiration par défaut de 30 secondes pour les types `command`, `http` et `mcp_tool`, plus court que la valeur par défaut de 600 secondes pour ces types sur la plupart des autres événements. Comme ce hook s'exécute avant chaque prompt et bloque le traitement du modèle jusqu'à sa fin, un hook bloqué paralyse la session. Si votre hook a besoin de plus de temps, définissez le champ `timeout` dans l'entrée du hook.1508Les hooks `UserPromptSubmit` ont un délai d'expiration par défaut de 30 secondes pour les types `command`, `http` et `mcp_tool`, plus court que la valeur par défaut de 600 secondes pour ces types sur la plupart des autres événements. Comme ce hook s'exécute avant chaque prompt et bloque le traitement du modèle jusqu'à sa fin, un hook bloqué paralyse la session. Si votre hook a besoin de plus de temps, définissez le champ `timeout` dans l'entrée du hook.
1421 1509
1422Hormis un hook de commande que vous exécutez avec [`async: true`](#run-hooks-in-the-background), un hook de commande, HTTP ou d'outil MCP `UserPromptSubmit` qui atteint son délai d'expiration est annulé et sa sortie, y compris tout `additionalContext`, est ignorée. Le prompt parvient tout de même à Claude, sans ce contexte. La transcription affiche un avis qui indique le nom du hook, le délai d'expiration atteint et le fait que la sortie a été ignorée.1510Hormis pour un hook de commande exécuté avec [`async: true`](#run-hooks-in-the-background), un hook `UserPromptSubmit` de type commande, HTTP ou outil MCP qui atteint son délai d'expiration est annulé et sa sortie, y compris tout `additionalContext`, est ignorée. Le prompt parvient tout de même à Claude, sans ce contexte. Pour bloquer plutôt le prompt, définissez [`onFailure: "block"`](#block-the-action-when-a-hook-fails) sur un hook de commande ou HTTP. La transcription affiche un avis indiquant le nom du hook, le délai d'expiration atteint et le fait que la sortie a été ignorée.
1423 1511
1424Un [hook de callback de l'Agent SDK](/docs/fr/agent-sdk/hooks) sur `UserPromptSubmit` qui atteint son délai d'expiration bloque le prompt avec un message indiquant le nom du hook et le délai d'expiration, car un callback à cet endroit peut servir de garde-fou de politique qui ne doit pas échouer en mode ouvert. La session se poursuit. Avant la v2.1.208, l'expiration d'un callback sur cet événement mettait fin au tour avec une erreur d'exécution.1512Un [hook de callback de l'Agent SDK](/docs/fr/agent-sdk/hooks) sur `UserPromptSubmit` qui atteint son délai d'expiration bloque le prompt avec un message indiquant le nom du hook et le délai d'expiration, car un callback à cet endroit peut servir de garde-fou de politique qui ne doit pas échouer en mode ouvert. La session se poursuit. Avant la v2.1.208, l'expiration d'un callback sur cet événement mettait fin au tour avec une erreur d'exécution.
1425 1513
1860| :- | :- | :- | :- |1948| :- | :- | :- | :- |
1861| `url` | string | `"https://example.com/api"` | URL à partir de laquelle récupérer le contenu |1949| `url` | string | `"https://example.com/api"` | URL à partir de laquelle récupérer le contenu |
1862| `prompt` | string | `"Extract the API endpoints"` | Prompt à exécuter sur le contenu récupéré |1950| `prompt` | string | `"Extract the API endpoints"` | Prompt à exécuter sur le contenu récupéré |
1951| `offset` | number | `100000` | Nombre facultatif de caractères à ignorer depuis le début de la page. Claude le définit pour poursuivre la lecture d'une page longue. Nécessite Claude Code v2.1.290 ou ultérieure |
1863 1952
1864<h5 id="websearch">1953<h5 id="websearch">
1865 WebSearch1954 WebSearch
2112| `message` | Pour `"deny"` uniquement : indique à Claude pourquoi la permission a été refusée |2201| `message` | Pour `"deny"` uniquement : indique à Claude pourquoi la permission a été refusée |
2113| `interrupt` | Pour `"deny"` uniquement : si `true`, arrête Claude |2202| `interrupt` | Pour `"deny"` uniquement : si `true`, arrête Claude |
2114 2203
2115Un hook qui se termine avec le code 2 sans objet `decision` laisse le flux de permission inchangé, et sa sortie stderr est ignorée. Seul l'objet `decision` peut accorder ou refuser la demande.2204Un hook qui se termine avec le code 2 sans objet `decision` laisse le flux de permissions inchangé, et sa sortie stderr est ignorée. Pour accorder ou refuser la demande, renvoyez l'objet `decision`.
2116 2205
2117```json theme={null}2206```json theme={null}
2118{2207{
2678 Contrôle de décision TaskCreated2767 Contrôle de décision TaskCreated
2679</h4>2768</h4>
2680 2769
2681Un hook TaskCreated peut bloquer la création de deux façons. Dans les deux cas, Claude Code supprime la tâche et renvoie votre message à Claude comme erreur de l'outil. Claude Code ignore `continue: false` pour cet événement et Claude continue de travailler.2770Un hook TaskCreated peut bloquer la création avec le code de sortie 2 ou avec une décision JSON. Dans les deux cas, Claude Code supprime la tâche et renvoie votre message à Claude comme erreur de l'outil. Claude Code ignore `continue: false` pour cet événement et Claude continue de travailler.
2682 2771
2683* **Code de sortie 2** : Claude Code renvoie le texte de stderr comme message.2772* **Code de sortie 2** : Claude Code renvoie le texte de stderr comme message.
2684* **JSON `{"decision": "block", "reason": "..."}`** : Claude Code renvoie `reason` comme message.2773* **JSON `{"decision": "block", "reason": "..."}`** : Claude Code renvoie `reason` comme message.
3561 3650
3562Claude Code affiche à l'utilisateur tout `systemMessage` renvoyé par votre hook, quelle que soit la décision ; un hook de rapport de coût peut donc renvoyer `{"systemMessage": "..."}` et se terminer avec 0.3651Claude Code affiche à l'utilisateur tout `systemMessage` renvoyé par votre hook, quelle que soit la décision ; un hook de rapport de coût peut donc renvoyer `{"systemMessage": "..."}` et se terminer avec 0.
3563 3652
3564Un hook PreModelSwitch qui ne répond pas avant son délai d'expiration bloque le changement. Pour [PreToolUse](#timeouts), en revanche, un hook de commande qui expire laisse l'appel d'outil se poursuivre. Le délai d'expiration par défaut pour cet événement est de 30 secondes. `PreModelSwitch` n'exécute que les hooks `command`, `http` et `mcp_tool` ; les valeurs par défaut de `prompt` et `agent` ne s'appliquent donc pas.3653Un hook PreModelSwitch qui ne répond pas avant son délai d'expiration bloque le changement. Pour savoir ce que provoque un délai d'expiration sur les autres événements, consultez [Délais d'expiration](#timeouts). Le délai d'expiration par défaut pour cet événement est de 30 secondes. `PreModelSwitch` n'exécute que des hooks `command`, `http` et `mcp_tool` ; les valeurs par défaut de `prompt` et `agent` ne s'appliquent donc pas.
3565 3654
3566Un hook qui se termine avec un code autre que 0 ou 2 et n'affiche aucune décision JSON ne bloque pas : Claude Code affiche son stderr et applique le changement, comme décrit dans [Autres codes de sortie](#other-exit-codes).3655Un hook qui se termine avec un code autre que 0 ou 2 et n'affiche aucune décision JSON constitue une erreur non bloquante, comme décrit dans [Autres codes de sortie](#other-exit-codes).
3567 3656
3568<h3 id="postmodelswitch">3657<h3 id="postmodelswitch">
3569 PostModelSwitch3658 PostModelSwitch
4279Les hooks asynchrones ont des contraintes supplémentaires par rapport aux hooks synchrones :4368Les hooks asynchrones ont des contraintes supplémentaires par rapport aux hooks synchrones :
4280 4369
4281* La sortie du hook est livrée au tour de conversation suivant. Si la session est inactive, la réponse attend jusqu'à la prochaine interaction utilisateur. Exception : un hook `asyncRewake` qui quitte avec le code 2 réveille Claude immédiatement même lorsque la session est inactive.4370* La sortie du hook est livrée au tour de conversation suivant. Si la session est inactive, la réponse attend jusqu'à la prochaine interaction utilisateur. Exception : un hook `asyncRewake` qui quitte avec le code 2 réveille Claude immédiatement même lorsque la session est inactive.
4282* Chaque exécution crée un processus en arrière-plan séparé. Il n'y a pas de déduplication sur plusieurs déclenchements du même hook asynchrone.4371* Chaque exécution crée un processus en arrière-plan séparé.
4283 4372
4284<h2 id="security-considerations">4373<h2 id="security-considerations">
4285 Considérations de sécurité4374 Considérations de sécurité