Stop burning tokens on Windows path errors.
Every time Claude Code generates a Bash command on Windows, there's a coin flip: will it use D:\Users\Tom\file.txt or /d/Users/Tom/file.txt? The wrong one fails, Claude reasons about the error, retries, sometimes fails again — and you pay for every token.
claude-code-pathfix makes the problem disappear. It's a zero-config PreToolUse hook that silently rewrites Windows paths to POSIX format before Bash commands execute. No errors. No retries. No wasted tokens.
Claude Code runs Bash (Git Bash / MSYS2) on Windows, but the AI constantly generates Windows-style paths:
# What Claude generates
cat D:\Users\Tom\.claude\settings.json
git -C C:\dev\myproject status
ls "C:\Program Files\Git\bin"
# What Git Bash actually needs
cat /d/Users/Tom/.claude/settings.json
git -C /c/dev/myproject status
ls "/c/Program Files/Git/bin"Each failure triggers a retry loop:
- Command fails → error message (tokens spent)
- Claude reasons about the error (more tokens spent)
- Claude retries with a corrected path (even more tokens)
- Sometimes repeats 3-4 times before succeeding
This is the most common source of wasted tokens on Windows. There are 15+ open issues about it in the Claude Code repo.
Install claude-code-pathfix and add two lines to your settings. Every Bash command is silently intercepted, paths are converted, and the corrected command executes on the first try.
Before: 3-4 attempts per path error × multiple errors per session = hundreds of wasted tokens
After: zero failures, zero retries, zero wasted tokens
The blog post Fixing Claude Code's PowerShell Problem with Hooks pioneered the idea of using hooks to catch Windows path errors. That approach blocks commands with bad paths and forces Claude to retry with the correct format — a "block-and-correct" pattern. The author reported going from "three attempts per PowerShell operation" to "zero failures."
claude-code-pathfix takes this further:
| netnerds.net approach | claude-code-pathfix | |
|---|---|---|
| Mechanism | Block the command, force a retry | Transparently rewrite the command |
| Retries needed | 1 (Claude must resubmit) | 0 (fixed before execution) |
| Tokens saved | ~60% of retry cost | ~100% of retry cost |
| Claude awareness | Claude sees the block, reasons about it | Claude never knows — command just works |
| Scope | PowerShell commands | All Bash commands |
The key difference: blocking still costs a round-trip. Claude sees the error, thinks about it, and resubmits — that's tokens spent on reasoning about a problem that could have been silently fixed. claude-code-pathfix uses Claude Code's updatedInput feature (shipped in v2.0.10) to rewrite the command in-flight. The AI never sees an error because there isn't one.
Inside Claude Code, run:
/plugin marketplace add fnrhombus/claude-plugins
/plugin install claude-code-pathfix@fnrhombus-plugins
Done. The hook is registered automatically — no settings.json edits required. Uninstall with /plugin uninstall claude-code-pathfix@fnrhombus-plugins.
The marketplace at
fnrhombus/claude-pluginsauto-discovers everyfnrhombusplugin tagged with theclaude-code-plugintopic, so adding it once gives you access to all of them.
Add this to your Claude Code settings (~/.claude/settings.json):
npx downloads and caches the package automatically on first run — no global install needed.
Or, have Claude Code configure itself:
claude -p --allowedTools "Edit(~/.claude/settings.json)" \
"Add a PreToolUse hook to your user settings.json: matcher 'Bash', type 'command', command 'npx -y claude-code-pathfix'"| Input | Output |
|---|---|
D:\Users\Tom\file.txt |
/d/Users/Tom/file.txt |
C:\dev\myproject\src\index.ts |
/c/dev/myproject/src/index.ts |
"C:\Program Files\Git\bin" |
"/c/Program Files/Git/bin" |
E:\data\export\ |
/e/data/export/ |
- Paths that are already POSIX (
/d/Users/Tom/...) - Relative paths with backslashes (
src\file.ts) — see tip below - URLs (
https://example.com) - Escape sequences (
\n,\t) - Non-path backslash usage (
grep 'foo\|bar')
Tip: This hook can only reliably detect Windows paths that start with a drive letter (
C:\...). Relative paths with backslashes (src\components\App.tsx) are ambiguous in bash and can't be safely distinguished from escape sequences. To get the most out of this hook, add the following to your project'sCLAUDE.md:Always use absolute paths in shell commands.
If a specific command needs its Windows paths left alone (e.g., passing a path to a Windows-native tool), prefix it with ⟪!⟫:
⟪!⟫somecommand C:\Users\Tom\file.txtThe prefix is stripped before execution — the command runs as somecommand C:\Users\Tom\file.txt with no path conversion. No restart or settings change needed.
If your Claude Code settings are symlinked across Windows and WSL (a common setup), claude-code-pathfix detects the platform at startup and silently exits on non-Windows systems. It will never interfere with native Linux or macOS Bash commands.
The hook is a tiny Node.js script built on @fnrhombus/claude-code-hooks, a strongly-typed wrapper for the Claude Code hook API. It starts in under 20ms — compared to 200-500ms for hooks that spawn a Bash subshell (#34457). You won't notice it's there.
- Claude Code's
PreToolUseevent fires before every Bash command claude-code-pathfixreads the command from stdin- A two-pass regex converts Windows absolute paths to POSIX format:
- Pass 1: quoted paths (handles spaces in paths like
"C:\Program Files\...") - Pass 2: unquoted paths
- Pass 1: quoted paths (handles spaces in paths like
- If any paths were converted, the fixed command is returned via
updatedInput - If nothing changed, the hook exits silently (no output = no modification)
- Claude Code v2.0.10+ (for
updatedInputhook support) - Node.js 20+
- Windows with Git Bash or MSYS2
If you find this project useful, consider supporting its development:
- GitHub Sponsors — Monthly sponsorship with public recognition
- Buy Me a Coffee — One-time or recurring donations
Your support helps maintain and improve this project!
MIT
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "npx -y claude-code-pathfix" } ] } ] } }