Windows पर Claude Code hooks काम नहीं कर रहे: वजहें और समाधान

जो hook Mac पर ठीक चलता है, वही Windows पर कुछ नहीं करता, या उससे भी बुरा, हर command को block कर देता है। लगभग हमेशा वजह shell होती है। यहाँ बताया गया है कि Claude Code Windows पर hooks कैसे चलाता है और अपने hooks को भरोसेमंद कैसे बनाएँ।

लेखक: Aslan, Pet Island टीम · अपडेट: 26 अक्टू॰ 2026 · पढ़ने में 5 मिनट

संक्षेप में

Windows पर Claude Code hook का command Git Bash से चलाता है, या Git Bash इंस्टॉल न होने पर PowerShell से। "shell": "powershell" या "shell": "bash" से साफ़ बताएँ कि आप कौन-सा चाहते हैं, stdout में सिर्फ़ एक JSON object रखें (profile का कोई echo नहीं), block करने के लिए exit code 2 इस्तेमाल करें, और Claude Code अपडेट करें (2.1.310 तक के versions में Windows hooks के कई bugs ठीक किए गए)। /hooks और claude --debug से debug करें।

आपका hook कौन-सा shell चलाता है

Claude Code command string को एक shell को देता है: macOS और Linux पर sh -c, Windows पर Git Bash, या Git Bash इंस्टॉल न होने पर PowerShell। Hooks reference का यह एक वाक्य “मेरे Mac पर तो चलता है” वाली ज़्यादातर रिपोर्टों को समझा देता है। PowerShell के लिए लिखा command Git Bash में fail होता है, bash script PowerShell में fail होती है, और आपको कौन-सा मिलेगा यह इस पर निर्भर है कि Git for Windows इंस्टॉल है या नहीं।

shell field से अंदाज़े की गुंजाइश ख़त्म करें। यह "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 को उसकी location पर सेट करें, फिर नया session शुरू करें।

लक्षण और उनकी वजहें

आपको क्या दिखता हैसंभावित वजहसमाधान
Hook कभी चलता हुआ नहीं लगतापुराना Claude Code version, ग़लत event या matcher, settings में invalid JSONअपडेट करें; /hooks जाँचें; comments और आख़िरी commas हटाएँ
ParserError या “unexpected token”PowerShell syntax Git Bash तक पहुँच रहा है, या इसका उल्टाshell साफ़ तौर पर सेट करें
Hook output “does not start with {”JSON से पहले कुछ print हुआ, अक्सर shell profile सेProfile output बंद करें; logs stderr पर भेजें
\ और / दोनों वाला मिला-जुला path नहीं मिलताWindows path variable को Unix-style suffix से जोड़ा गयाExec form इस्तेमाल करें: program command में, हर argument args में
Git Bash से powershell: Permission denied2.1.283 और 2.1.304 से 2.1.305 में कभी-कभी रिपोर्ट हुआ (#103910, खुला है)"shell": "powershell" इस्तेमाल करें ताकि बीच में Git Bash न रहे
Guard hook हर चीज़ को जाने देता है2 की जगह exit code 1, या पुराने versions में fail-open bugBlock करने के लिए exit 2; 2.1.310 या नए पर अपडेट करें
Hook बिना किसी output के तुरंत लौट आता हैGUI-subsystem program, जिसका shell इंतज़ार नहीं करताConsole program इस्तेमाल करें, या process का इंतज़ार करें

stdout पर सिर्फ़ JSON

Claude Code आपके hook के standard output को उसका जवाब मानता है। Docs का नियम छोटा है: stdout पर JSON object के अलावा कुछ भी print न करें। Windows पर यह चुपके से टूटता है: Git Bash और कुछ setups अब भी आपकी shell profile load करते हैं, और उस profile का बिना शर्त वाला echo आपके JSON से पहले जुड़ जाता है। तब hook terminal में “काम करता है” और Claude Code के अंदर fail होता है।

इसकी जगह logs किसी फ़ाइल या stderr पर लिखें, और अपनी profile का output सिर्फ़ interactive shell में दिखने दें।

Exit codes: 2 block करता है, 1 नहीं

Exit 0 का मतलब सफलता है। Exit 2 एक blocking error है: जिन events को block किया जा सकता है, उन पर Claude Code action रोक देता है और आपका stderr दिखाता है। Valid JSON के बिना exit 1 non-blocking error है, और action आगे बढ़ जाता है। अगर आपका hook कोई policy लागू करता है, तो exit 2 इस्तेमाल करें।

हर event को इस तरह block नहीं किया जा सकता। Notification hook का exit code ignore किया जाता है। Exit 2 देने वाला Stop hook Claude से काम जारी करवाता है। PermissionRequest hook exit 2 को पूरी तरह ignore करता है। वह अपने JSON में decision object से फ़ैसला करता है।

Claude Code 2.1.309 ने वह समस्या ठीक की जिसमें hook का program code 2 के साथ exit होने पर भी PowerShell hooks block नहीं करते थे। अगर आपका PowerShell guard ignore होता लगता है, तो पहले अपना version जाँचें।

Windows के वे fixes जिनके लिए अपडेट करना फ़ायदेमंद है

Anthropic के changelog में Windows hook fixes की लंबी सूची है। इनमें से ये fixes पुराने forum threads की वजह समझाते हैं:

VersionFix
2.1.47PreToolUse और PostToolUse hooks Windows पर चुपचाप fail होते थे; अब वे cmd.exe की जगह Git Bash से चलते हैं
2.1.161bash को सीधे call करने वाले hooks (/usr/bin/bash script.sh) “command not found” के साथ fail होते थे
2.1.299जिन PreToolUse और PermissionRequest hooks में shell सेट नहीं था, वे Git for Windows के बिना fail open होते थे; अब fail होने वाला guard block करता है
2.1.309PowerShell hooks exit code 2 पर block नहीं करते थे; "shell": "powershell" वाले guards Git for Windows के बिना fail open होते थे
2.1.310जिन guards का command सिर्फ़ quoted strings था (जैसे quoted path), वे Git Bash के बिना fail open होते थे

“No hook is working on Windows” शीर्षक वाला पुराना issue (#10450) 2.0.27 पर रिपोर्ट हुआ था; एक commenter ने पाया कि वजह यह थी कि stdin hook commands तक नहीं पहुँच रहा था। अगर आप इतने पुराने version पर हैं, तो कुछ और debug करने से पहले अपडेट करें।

Program को सीधे call करना

अगर आपका hook एक compiled program है, तो आप exec form से shell को छोड़ सकते हैं (args field; args सेट होने पर shell ignore होता है)। Windows पर exec form के लिए ज़रूरी है कि command किसी असली executable पर resolve हो, जैसे .exe; .cmd और .bat shims (npm जो ज़्यादातर चीज़ें इंस्टॉल करता है वे भी) shell के बिना spawn नहीं हो सकते। .exe की ओर point करें, या shell form इस्तेमाल करें।

अपना hook helper बनाते समय हमें एक सबक़ मिला: Windows पर जब shell GUI subsystem के लिए बना कोई program शुरू करता है, तो उसके ख़त्म होने का इंतज़ार नहीं करता। Shell तुरंत लौट आता है, एजेंट खाली output पढ़ता है, और hook मरा हुआ लगता है। Hook programs का console programs होना ज़रूरी है।

Plugin hooks और paths

${CLAUDE_PLUGIN_ROOT}/hooks/run.sh जैसे paths बनाने वाले plugin hooks Windows पर v2.1.2 और v2.1.12 के बीच टूट गए थे (#18610): variable backslash वाले path में expand होता है, और उसमें forward-slash suffix जोड़ने से ऐसा मिला-जुला path बनता है जिसे bash resolve नहीं कर पाता। मौजूदा docs साफ़ समाधान देते हैं: जब भी कोई hook path placeholder इस्तेमाल करे, exec form इस्तेमाल करें। Program को command में और हर argument को args में रखें, जैसे "command": "node", "args": ["${CLAUDE_PLUGIN_ROOT}/scripts/format.js"]। हर element एक argument के रूप में जाता है, और उसे बिगाड़ने के लिए कोई shell नहीं होता।

Debugging checklist

  1. /hooks हर configured hook और उसके source की read-only list खोलता है।
  2. claude --debug (या session के बीच /debug) हर hook run, उसका output और exit code दिखाता है। claude --debug-file <path> इसे एक फ़ाइल में लिखता है।
  3. JSON validate करें। Settings फ़ाइलें strict JSON होती हैं; आख़िर में एक अतिरिक्त comma पूरी फ़ाइल को बंद कर देता है।
  4. Matcher जाँचें। Matchers case-sensitive होते हैं; "*", "" या matcher न होना हर चीज़ से match करता है।
  5. Command ख़ुद चलाएँ, उसी shell में जो Claude Code इस्तेमाल करेगा, sample JSON pipe करके।
  6. Timeout देखें। Command hooks का default 600 सेकंड है; किसी व्यक्ति का इंतज़ार करने वाले hook को इतनी गुंजाइश चाहिए।

जाँच के दौरान हर hook बंद करने के लिए "disableAllHooks": true सेट करें।

अगर आप सिर्फ़ notifications और approvals चाहते थे

Windows पर कई hook setups सिर्फ़ एक वजह से होते हैं: यह जानना कि Claude Code को कब आपकी ज़रूरत है, और उसे जवाब देना। Pet Island यह बिना किसी scripting के करता है। यह एक click में Claude Code से जुड़ता है, आपके लिए Windows की बारीकियाँ संभालता है, और हर permission request, सवाल और plan को command या diff के साथ स्क्रीन के ऊपर एक छोटे island पर रखता है, जहाँ आप उसे allow या deny करते हैं। यह तब भी काम करता है जब Claude Code WSL के अंदर चलता है।

अक्सर पूछे जाने वाले सवाल

Windows पर Claude Code hooks कौन-सा shell चलाता है?

Git Bash, या Git Bash इंस्टॉल न होने पर PowerShell। साफ़ तौर पर चुनने के लिए hook में "shell": "powershell" या "shell": "bash" सेट करें।

मेरा Claude Code hook terminal में काम करता है लेकिन Claude Code में क्यों नहीं?

आमतौर पर अतिरिक्त output की वजह से: text echo करने वाली shell profile hook के JSON से पहले जुड़ जाती है। stdout पर सिर्फ़ JSON object print करें।

Hook से किसी tool call को block कैसे करवाऊँ?

Code 2 के साथ exit करें (या JSON में deny decision लौटाएँ)। Exit code 1 non-blocking error है और action आगे बढ़ जाता है। PermissionRequest hooks exit 2 को ignore करते हैं और इसकी जगह decision object इस्तेमाल करते हैं।

क्या hook command कोई .cmd या .bat फ़ाइल हो सकती है?

Exec form में नहीं। Windows पर इसे किसी असली executable पर resolve होना चाहिए, जैसे .exe। .cmd या .bat फ़ाइलें चलाने के लिए shell form इस्तेमाल करें।

कैसे देखूँ कि hook क्यों fail हुआ?

claude --debug चलाएँ या /debug टाइप करें, और कौन-से hooks load हुए हैं यह देखने के लिए /hooks इस्तेमाल करें।

स्रोत

इस पेज की हर setting और हर व्यवहार को 26 अक्टूबर 2026 को इन पेजों से मिलाकर जाँचा गया। एजेंट तेज़ी से बदलते हैं; अगर कुछ अब मेल नहीं खाता, तो आधिकारिक पेज ही मान्य है।

आगे पढ़ें

हर एजेंट को अपनी स्क्रीन के ऊपर से जवाब दें।

Windows और Mac · 7 दिन मुफ़्त, फिर एक बार $8.99 · हर बिक्री से $1 सड़क के बेसहारा जानवरों के खाने पर जाता है

Pet Island मुफ़्त आज़माएँ