Skip to content

fnrhombus/claude-code-pathfix

Repository files navigation

claude-code-pathfix

Stop burning tokens on Windows path errors.

npm version license

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.

The problem

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:

  1. Command fails → error message (tokens spent)
  2. Claude reasons about the error (more tokens spent)
  3. Claude retries with a corrected path (even more tokens)
  4. 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.

The fix

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

Prior art

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.

Install

Option 1: Claude Code plugin (recommended)

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-plugins auto-discovers every fnrhombus plugin tagged with the claude-code-plugin topic, so adding it once gives you access to all of them.

Option 2: npm + settings.json

Add this to your Claude Code settings (~/.claude/settings.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "npx -y claude-code-pathfix"
          }
        ]
      }
    ]
  }
}

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'"

What it converts

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/

What it doesn't touch

  • 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's CLAUDE.md:

Always use absolute paths in shell commands.

Escape hatch

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.txt

The 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.

Cross-platform safe

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.

Performance

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.

How it works

  1. Claude Code's PreToolUse event fires before every Bash command
  2. claude-code-pathfix reads the command from stdin
  3. 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
  4. If any paths were converted, the fixed command is returned via updatedInput
  5. If nothing changed, the hook exits silently (no output = no modification)

Requirements

  • Claude Code v2.0.10+ (for updatedInput hook support)
  • Node.js 20+
  • Windows with Git Bash or MSYS2

Support

If you find this project useful, consider supporting its development:

Your support helps maintain and improve this project!

License

MIT

About

Claude Code hook that transparently converts Windows paths to POSIX in Bash commands — eliminating retry loops and saving tokens

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors