{"slug": "my-claude-code-hook-silently-ate-every-korean-character-and-it-took-me-an-hour", "title": "My Claude Code hook silently ate every Korean character, and it took me an hour to figure out why", "summary": "A developer spent an hour debugging a Claude Code hook on Windows that silently failed to match Korean-language prompts. The issue was not in the code logic but in Windows PowerShell 5.1's file encoding: the `.ps1` script, saved as plain UTF-8 without a byte-order mark, reinterpreted Korean characters as garbage at parse time, causing regex patterns to silently fail without errors. The fix required re-saving the script with a UTF-8 BOM, a problem that pure-ASCII scripts never trigger.", "body_md": "I spent an hour last week debugging a hook that wasn't broken.\n\nHere's the setup: I run Claude Code on Windows, and I'd written a little `UserPromptSubmit`\n\nhook in PowerShell — a keyword router that reads my prompt and, if it sees something like `mcp 서버`\n\nor `코드 리뷰`\n\n, injects a hint so Claude pulls up the right skill. Half my prompts are in Korean, so a bunch of the regex patterns had Korean in them.\n\nIt worked perfectly for the English rules. The Korean ones? Dead. No match, no error, no log line. The script ran, exited 0, and just... did nothing for half my inputs.\n\nI did all the dumb things first. Echoed the prompt — looked fine. Tested the regex in a PowerShell console — matched fine. Re-read the JSON parsing five times. Added `Write-Host`\n\ndebugging everywhere. Nothing.\n\nThe actual problem had nothing to do with my code. It was the **file encoding**.\n\nWindows PowerShell 5.1 (the default `powershell.exe`\n\n, not `pwsh`\n\n) does not assume UTF-8 when it reads a `.ps1`\n\nfile. If there's no byte-order mark, it falls back to the legacy system code page. So my script — saved as plain UTF-8 by my editor — got its Korean bytes reinterpreted as garbage *at parse time*, before a single line ran. The regex literal that was supposed to be `코드.?리뷰`\n\nbecame mojibake, which of course never matches anything real. And because it's a parse-level reinterpretation, you don't get an error. You get silence.\n\nThe fix is one line, once you know:\n\n``` php\nfunction Add-Bom($path) {\n  $text = [System.IO.File]::ReadAllText($path)\n  $enc  = New-Object System.Text.UTF8Encoding $true   # $true = write the BOM\n  [System.IO.File]::WriteAllText($path, $text, $enc)\n}\nAdd-Bom \"$env:USERPROFILE\\.claude\\skill-router.ps1\"\n```\n\nRe-save with a BOM and everything lights up. Pure-ASCII scripts don't care, which is exactly why every example you find online \"works\" — almost all of them are bash on macOS, and the handful of PowerShell ones never have a non-ASCII character to trip over.\n\nThat bug annoyed me enough that I went and cleaned up my whole Claude Code setup so I'd never have to rediscover this stuff. A few things that were worth keeping:\n\n`rm -rf /`\n\n, `DROP TABLE`\n\n, `git push --force`\n\n, `taskkill`\n\n, a disk format, etc. It doesn't hard-block — it injects a \"show this to the user and confirm first\" instruction. Saved me from a `--hard`\n\nreset I didn't mean to approve.`chcp 65001`\n\n+ a temp file + stdin redirect — don't ask how long that took either).I put it all up here, MIT, free: [https://github.com/coding-jhj/claude-pwsh-kit](https://github.com/coding-jhj/claude-pwsh-kit)\n\nIt's not magic and it won't make Claude smarter. It's plumbing — guardrails, routing, and a setup guide that tells you about the BOM thing on page one so you don't lose the hour I lost.\n\nIf you're on Windows and your hooks are misbehaving in ways that make no sense, check your encoding before you check your logic. And if you've hit other PowerShell-specific Claude Code papercuts, tell me — I'd rather fix them in the repo than rediscover them at 1am.", "url": "https://wpnews.pro/news/my-claude-code-hook-silently-ate-every-korean-character-and-it-took-me-an-hour", "canonical_source": "https://dev.to/codingjhj/my-claude-code-hook-silently-ate-every-korean-character-and-it-took-me-an-hour-to-figure-out-why-3ii4", "published_at": "2026-06-06 03:48:06+00:00", "updated_at": "2026-06-06 04:12:02.737210+00:00", "lang": "en", "topics": ["ai-tools", "large-language-models", "ai-products"], "entities": ["Claude Code", "Windows PowerShell", "PowerShell"], "alternates": {"html": "https://wpnews.pro/news/my-claude-code-hook-silently-ate-every-korean-character-and-it-took-me-an-hour", "markdown": "https://wpnews.pro/news/my-claude-code-hook-silently-ate-every-korean-character-and-it-took-me-an-hour.md", "text": "https://wpnews.pro/news/my-claude-code-hook-silently-ate-every-korean-character-and-it-took-me-an-hour.txt", "jsonld": "https://wpnews.pro/news/my-claude-code-hook-silently-ate-every-korean-character-and-it-took-me-an-hour.jsonld"}}