What is it like to spend an hour debugging a hook that isn’t actually broken? Last week, a developer using Anthropic's CLI tool, Claude Code, experienced exactly this nightmare on Windows. They had set up a UserPromptSubmit hook written in PowerShell—a keyword router designed to parse prompts and inject context hints when detecting terms like "mcp" or "코드 리뷰" (code review). Since half of the developer's prompts were in Korean, several regex patterns contained non-ASCII Korean characters.
The English rules worked flawlessly. However, the Korean ones remained completely dead—yielding no matches, no errors, and no logs. The script exited with code 0 but did absolutely nothing for non-ASCII inputs. After trying common debugging steps, including echoing prompts, testing regex in the console, and adding verbose Write-Host logging, the author discovered that the root cause was not the code itself, but file encoding.
By default, Windows PowerShell 5.1 (powershell.exe, not pwsh) does not assume UTF-8 when reading a .ps1 file. Without a Byte Order Mark (BOM), it falls back to the legacy system code page. Consequently, the script—saved as plain UTF-8 by modern text editors—had its Korean bytes reinterpreted as garbled characters (mojibake) during parsing. Since this mismatch occurs at the parsing stage, it silently fails without throwing runtime exceptions.
The fix is straightforward once identified: force-saving the script with a UTF-8 BOM using a PowerShell helper function:
function Add-Bom($path) {
$text = [System.IO.File]::ReadAllText($path)
$enc = New-Object System.Text.UTF8Encoding $true
[System.IO.File]::WriteAllText($path, $text, $enc)
}
Add-Bom "$env:USERPROFILE\.claude\skill-router.ps1"Pure-ASCII scripts are unaffected, which is why almost all macOS and Linux bash-based examples found online work seamlessly, while Windows users frequently run into this silent failure.
Frustrated by this bug, the author cleaned up their Claude Code configuration and shared several highly practical tools: a PreToolUse safety hook that intercepts destructive actions (e.g., rm -rf /, DROP TABLE, git push --force) to prompt for user confirmation; a sanitized, documented keyword router template; and a regression testing harness to verify routing rules.
[AgentUpdate Depth Analysis] The emergence of terminal-native AI tools like Claude Code marks a paradigm shift from simple chatbots to highly integrated, action-oriented AI Agents. This encoding bug highlights a fundamental vulnerability in the emerging Agent ecosystem: the misalignment between LLM reasoning and legacy operating system environments. Because AI Agents depend on system I/O, configuration files, and standard input/output streams, minor character encoding discrepancies can quietly break the critical feedback loop. To build robust enterprise-grade AI Agent architectures, developers must implement "defensive prompting" and runtime safety guards—such as the PreToolUse lifecycle hooks demonstrated here. Safeguarding terminal-level operations is no longer optional; it is a baseline requirement for preventing catastrophic actions and ensuring predictable Agent behavior in heterogeneous production environments.