Хуки Claude Code не працюють у Windows: причини й рішення

Хук, який чудово працює на Mac, у Windows нічого не робить або, що гірше, блокує кожну команду. Майже завжди справа в оболонці. Нижче описано, як Claude Code запускає хуки у Windows і як зробити ваші хуки надійними.

Автор: Aslan, команда Pet Island · Оновлено 26 жовт. 2026 р. · 5 хв читання

КОРОТКО

У Windows Claude Code запускає command хука через Git Bash, а якщо Git Bash не встановлено, через PowerShell. Явно вкажіть потрібну оболонку за допомогою "shell": "powershell" або "shell": "bash", виводьте в stdout лише один об’єкт JSON (без echo з профілю), використовуйте код виходу 2 для блокування й оновіть Claude Code (кілька помилок хуків у Windows виправлено у версіях до 2.1.310). Для налагодження використовуйте /hooks і claude --debug.

Яка оболонка запускає ваш хук

Claude Code передає рядок command оболонці: sh -c у macOS і Linux, Git Bash у Windows або PowerShell, якщо Git Bash не встановлено. Це одне речення з довідника з хуків пояснює більшість скарг «а на моєму Mac працює». Команда, написана для PowerShell, падає в Git Bash, bash-скрипт падає в PowerShell, а яка оболонка вам дістанеться, залежить від того, чи встановлено випадково Git for Windows.

Приберіть невизначеність за допомогою поля shell. Воно приймає "bash" або "powershell":

%USERPROFILE%\.claude\settings.jsonКопіювати
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"shell": "powershell",
"command": "[Console]::Beep(880, 200)"
}
]
}
]
}
}

Якщо вам потрібен Git Bash, а Claude Code не може його знайти, встановіть Git for Windows або вкажіть його розташування в CLAUDE_CODE_GIT_BASH_PATH, потім почніть нову сесію.

Симптоми та їхні причини

Що ви бачитеІмовірна причинаРішення
Хук, схоже, взагалі не запускаєтьсяСтара версія Claude Code, неправильна подія або matcher, некоректний JSON у налаштуванняхОновіться; перевірте /hooks; приберіть коментарі й кінцеві коми
ParserError або «unexpected token»Синтаксис PowerShell потрапляє в Git Bash або навпакиЯвно задайте shell
Виведення хука «does not start with {»Перед JSON щось виводиться, часто профіль оболонкиВимкніть виведення профілю; пишіть логи в stderr
Не знаходиться шлях, у якому змішано \ і /Змінну зі шляхом Windows склеєно із суфіксом у стилі UnixВикористовуйте exec-форму: програма в command, кожен аргумент в args
powershell: Permission denied з Git BashПеріодично трапляється у 2.1.283 і 2.1.304–2.1.305 (#103910, відкритий)Використовуйте "shell": "powershell", щоб виключити Git Bash із ланцюжка
Захисний хук пропускає всеКод виходу 1 замість 2 або помилка fail-open у старих версіяхДля блокування завершуйте хук із кодом 2; оновіться до 2.1.310 або новішої
Хук миттєво завершується без виведенняПрограма підсистеми GUI, завершення якої оболонка не чекаєВикористовуйте консольну програму або чекайте завершення процесу

У stdout лише JSON

Claude Code зчитує стандартне виведення хука як його відповідь. Правило в документації коротке: не виводьте в stdout нічого, крім об’єкта JSON. У Windows воно порушується непомітно: Git Bash і деякі конфігурації однаково завантажують профіль оболонки, і безумовний echo у цьому профілі додається перед вашим JSON. У результаті хук «працює» в терміналі й падає всередині Claude Code.

Пишіть логи у файл або в stderr, а виведення в профілі робіть лише для інтерактивної оболонки.

Коди виходу: 2 блокує, 1 ні

Код виходу 0 означає успіх. Код 2 означає блокувальну помилку: на подіях, які можна заблокувати, Claude Code зупиняє дію і показує ваш stderr. Код 1 без коректного JSON вважається неблокувальною помилкою, і дія виконується. Якщо хук забезпечує дотримання політики, використовуйте код 2.

Не кожну подію можна так заблокувати. Код виходу хука Notification ігнорується. Хук Stop, що завершився з кодом 2, змушує Claude продовжувати роботу. Хук PermissionRequest повністю ігнорує код 2. Він ухвалює рішення через об’єкт decision у своєму JSON.

У Claude Code 2.1.309 виправлено помилку, через яку хуки PowerShell не блокували дію, коли програма хука завершувалася з кодом 2. Якщо ваш захисний хук на PowerShell ніби ігнорується, спершу перевірте версію.

Виправлення для Windows, заради яких варто оновитися

У журналі змін Anthropic накопичилося багато виправлень хуків для Windows. Ось ті, які пояснюють старі обговорення на форумах:

ВерсіяВиправлення
2.1.47Хуки PreToolUse і PostToolUse мовчки не спрацьовували у Windows; тепер вони запускаються через Git Bash замість cmd.exe
2.1.161Хуки, що явно викликають bash (/usr/bin/bash script.sh), падали з «command not found»
2.1.299Хуки PreToolUse і PermissionRequest без заданої оболонки спрацьовували як fail-open без Git for Windows; тепер захисний хук, що впав, блокує дію
2.1.309Хуки PowerShell не блокували при коді виходу 2; захисні хуки з "shell": "powershell" спрацьовували як fail-open без Git for Windows
2.1.310Захисні хуки, у яких команда складалася лише з рядків у лапках (наприклад, шляху в лапках), спрацьовували як fail-open без Git Bash

Старий issue із заголовком «No hook is working on Windows» (#10450) було створено для версії 2.0.27; один із коментаторів з’ясував, що stdin не доходив до команд хуків. Якщо у вас настільки стара версія, оновіться, перш ніж щось налагоджувати.

Прямий виклик програми

Якщо ваш хук — скомпільована програма, можна обійтися без оболонки, використовуючи exec-форму (поле args; якщо задано args, shell ігнорується). У Windows exec-форма вимагає, щоб command вказував на справжній виконуваний файл, наприклад .exe; обгортки .cmd і .bat (зокрема більшість того, що встановлює npm) неможливо запустити без оболонки. Вкажіть .exe або використовуйте форму з оболонкою.

Один урок із розробки нашого власного помічника для хуків: у Windows оболонка не чекає завершення програми, зібраної для підсистеми GUI. Оболонка одразу повертає керування, агент читає порожнє виведення, і хук виглядає мертвим. Програми хуків мають бути консольними.

Хуки плагінів і шляхи

Хуки плагінів, що збирають шляхи на кшталт ${CLAUDE_PLUGIN_ROOT}/hooks/run.sh, перестали працювати у Windows між v2.1.2 і v2.1.12 (#18610): змінна розгортається у шлях зі зворотними скісними рисками, а доданий суфікс із прямими скісними рисками дає змішаний шлях, який bash не може розв’язати. Актуальна документація пропонує чисте рішення: використовуйте exec-форму щоразу, коли хук посилається на плейсхолдер шляху. Помістіть програму в command, а кожен аргумент в args, наприклад "command": "node", "args": ["${CLAUDE_PLUGIN_ROOT}/scripts/format.js"]. Кожен елемент передається як один аргумент, і немає оболонки, яка могла б його спотворити.

Чек-лист налагодження

  1. /hooks відкриває список усіх налаштованих хуків лише для читання із зазначенням, звідки взявся кожен.
  2. claude --debug (або /debug посеред сесії) показує кожен запуск хука, його виведення й код виходу. claude --debug-file <path> записує це у файл.
  3. Перевірте JSON. Файли налаштувань — це строгий JSON; одна кінцева кома вимикає весь файл.
  4. Перевірте matcher. Matcher чутливий до регістру; "*", "" або відсутність matcher збігається з усім.
  5. Запустіть команду самі в тій самій оболонці, яку використовуватиме Claude Code, передавши на вхід приклад JSON.
  6. Подивіться на тайм-аут. У командних хуків за замовчуванням 600 секунд; хуку, який чекає на людину, потрібен цей запас.

Щоб на час розслідування вимкнути всі хуки, задайте "disableAllHooks": true.

Якщо вам потрібні були лише сповіщення й підтвердження

Багато конфігурацій хуків у Windows існують заради одного: дізнаватися, коли ви потрібні Claude Code, і відповідати йому. Pet Island робить це без жодних скриптів. Він підключається до Claude Code одним клацанням, сам розв’язує всі тонкощі Windows і виводить кожен запит дозволу, запитання і план на маленький острів у верхній частині екрана разом із командою або diff, де ви дозволяєте або забороняєте дію. Він працює і тоді, коли Claude Code запущено всередині WSL.

Поширені запитання

Яка оболонка запускає хуки Claude Code у Windows?

Git Bash, а якщо Git Bash не встановлено, PowerShell. Щоб вибрати явно, задайте в хуку "shell": "powershell" або "shell": "bash".

Чому мій хук Claude Code працює в терміналі, але не в Claude Code?

Зазвичай через зайве виведення: профіль оболонки, який виводить текст через echo, додає його перед JSON хука. Виводьте в stdout лише об’єкт JSON.

Як зробити, щоб хук блокував виклик інструмента?

Завершуйте хук із кодом 2 (або поверніть рішення deny у JSON). Код виходу 1 — це неблокувальна помилка, і дія виконується. Хуки PermissionRequest ігнорують код 2 і натомість використовують об’єкт decision.

Чи може командою хука бути файл .cmd або .bat?

Не в exec-формі. У Windows команда має вказувати на справжній виконуваний файл, наприклад .exe. Щоб запускати файли .cmd або .bat, використовуйте форму з оболонкою.

Як дізнатися, чому хук не спрацював?

Запустіть claude --debug або введіть /debug, а за допомогою /hooks подивіться, які хуки завантажено.

Джерела

Усі налаштування й описану поведінку на цій сторінці звірено з цими джерелами 26 жовтня 2026 р.. Агенти швидко змінюються; якщо щось уже не збігається, пріоритет має офіційна сторінка.

ЧИТАЙТЕ ТАКОЖ

Відповідайте будь-якому агенту просто з верхньої частини екрана.

Windows і Mac · 7 днів безплатно, потім $8.99 одноразово · $1 з кожного продажу йде на корм безпритульним тваринам

Спробувати Pet Island безплатно