Hooks don't receive tool input for Read/Glob; permission patterns don't match tilde paths

Status Closed — not planned
Maintainer reply None cached
Activity 13 comments · opened Jan 12, 2026 · closed Mar 1, 2026

Summary

PreToolUse hooks for Read/Glob tools do not receive tool input parameters as environment variables, making it impossible to validate or intercept file paths before execution. Additionally, permission patterns containing tilde (~) do not match agent-generated tilde paths.

Environment

  • Claude Code v2.1.5
  • Windows 11 (Git Bash / MINGW64)
  • Model: Opus 4.5

Problem 1: Hooks don't receive tool input for Read/Glob

Expected Behavior

PreToolUse hooks should receive tool input parameters as environment variables, similar to how Bash hooks receive CLAUDE_TOOL_INPUT_COMMAND.

For Read: CLAUDE_TOOL_INPUT_FILE_PATH
For Glob: CLAUDE_TOOL_INPUT_PATH and CLAUDE_TOOL_INPUT_PATTERN

Actual Behavior

Hooks only receive:

  • CLAUDE_PROJECT_DIR
  • CLAUDE_CODE_ENTRYPOINT

No tool-specific input variables are provided. This was verified by dumping all environment variables from within the hook.

Impact

Cannot create hooks to validate/fix file paths before tool execution. This is critical for Windows environments where path format issues cause permission prompts.

Problem 2: Permission patterns don't match tilde paths

Setup

User-level ~/.claude/settings.local.json contains:

{
  "permissions": {
    "allow": [
      "Read(~\Projects\**)",
      "Read(~/Projects/**)",
      "Glob(~\Projects\**)"
    ]
  }
}

Expected Behavior

These patterns should match paths like ~\Projects\Aletheia-310\src\file.py

Actual Behavior

Permission prompt appears:

Read(~\Projects\Aletheia-310\src\lambda_function.py)
Do you want to proceed?

The pattern Read(~\Projects\**) does not match ~\Projects\Aletheia-310\...

Problem 3: Model generates tilde paths despite explicit instructions

Even with explicit prompt instructions like:

PATH FORMATS (MANDATORY):
- Read/Write/Edit/Glob: C:\Users\mcwiz\Projects\Aletheia\path\to\file
- NEVER use ~ or ~\ - these are FORBIDDEN

And CLAUDE.md containing:

THE TILDE CHARACTER (~) DOES NOT EXIST. NEVER USE IT.

Opus still generates:

Read(~\Projects\Aletheia-310\src\etymologist.py)

Note: The Claude Code banner itself displays ~\Projects\Aletheia which may be where the model picks up this format.

Reproduction Steps

  1. On Windows, create a worktree in a subdirectory
  2. Configure a PreToolUse hook for Read that logs all environment variables
  3. Have the model attempt to Read a file in the worktree
  4. Observe: hook receives no file path information
  5. Observe: permission prompt appears despite matching patterns in settings

Requested Fixes

  1. Expose tool input to hooks - Provide CLAUDE_TOOL_INPUT_* environment variables for all tools, not just Bash
  2. Fix tilde pattern matching - Ensure Read(~\Projects\**) matches ~\Projects\... paths
  3. Consider normalizing paths - Before permission check, normalize tilde paths to absolute paths

Workaround Attempted

Added Read(**) and Glob(**) to allow any path - testing pending.

View original on GitHub ↗

13 Comments

github-actions[bot] · 7 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/16800
  2. https://github.com/anthropics/claude-code/issues/17424
  3. https://github.com/anthropics/claude-code/issues/9567

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

martymcenroe · 7 months ago

Additional Finding: Pattern matching is completely broken

After further testing, even the most permissive patterns don't work:

  1. Read(**) - Does NOT match any Read calls
  2. Glob(**) - Does NOT match any Glob calls
  3. Search(**) - Does NOT match any Search calls
  4. Bash(gemini:*) - Does NOT match gemini -p "..." commands

User is still prompted for approval on EVERY Read/Search/Glob operation and even Bash commands that should match existing patterns.

The permission pattern matching system appears to be completely non-functional. No patterns are matching, regardless of specificity or wildcards.

This is blocking automated agent workflows entirely.

martymcenroe · 7 months ago

Additional Bug: | Inside Quoted Strings Triggers Approval

Related to the pattern matching issues above, I've discovered another problem:

Command that triggers approval prompt:

gemini -p "Review this document. First read GEMINI.md for your | identity handshake..."

Why this should NOT trigger approval:

  • The | character is inside a double-quoted string
  • It is NOT a shell pipe operator
  • It's literal text being passed to the gemini command

Expected behavior: Commands with | inside quoted strings should not be flagged as containing shell operators.

Actual behavior: The entire command is flagged for approval.

Root cause hypothesis: The permission system does a naive string scan for | anywhere in the command, without parsing to understand shell quoting context.

This affects any command that passes text containing | as an argument, which is common when invoking AI tools that receive natural language prompts.

martymcenroe · 7 months ago

Re: Potential Duplicates

I've reviewed the linked issues:

  • #16800 (CLOSED): Absolute paths converted to tilde - Related but opposite direction (paths being converted TO tilde rather than FROM tilde)
  • #17424 (OPEN): PreToolUse hooks receive empty stdin on Windows - Same as Problem 1 in this issue
  • #9567 (CLOSED): Hook environment variables empty - Same underlying issue

What's UNIQUE in this issue that's NOT covered elsewhere:

Pattern Matching is Completely Non-Functional

The most severe finding is that no permission patterns match anything, regardless of format:

{
  "allow": [
    "Read(**)",      // Should match ALL reads - doesn't work
    "Glob(**)",      // Should match ALL globs - doesn't work
    "Search(**)",    // Should match ALL searches - doesn't work
    "Read(*)",       // Alternative syntax - doesn't work
    "Bash(gemini:*)" // Should match gemini commands - doesn't work
  ]
}

User is STILL prompted for approval on EVERY operation. The entire permission system appears non-functional on Windows.

This is distinct from the tilde-specific path issues in #16800. Even with the most permissive wildcards possible, nothing auto-approves.

The | Inside Quotes Issue

Additionally, Bash commands containing | inside quoted strings (not as shell operators) trigger approval prompts. This is likely due to naive string scanning rather than proper shell parsing.

---

I'll close the duplicate aspects (hooks stdin - same as #17424), but please keep this open for:

  1. Complete pattern matching failure
  2. | inside quotes triggering approval

👎 (preventing auto-closure)

martymcenroe · 7 months ago

Edit Tool Also Affected

Pattern matching is also broken for the Edit tool:

Configured permission:

"Edit(C:\Users\mcwiz\Projects\**)"

Prompts still appearing:

Do you want to make this edit to etymologist.py?
Do you want to make this edit to overlay.js?

These files are at:

  • C:\Users\mcwiz\Projects\Aletheia-310\src\etymologist.py
  • C:\Users\mcwiz\Projects\Aletheia-310\extensions\chrome\overlay.js

Both clearly match C:\Users\mcwiz\Projects\** but prompts appear anyway.

Summary of broken tools:

  • Read(**) - doesn't match
  • Glob(**) - doesn't match
  • Search(**) - doesn't match
  • Edit(C:\Users\mcwiz\Projects\**) - doesn't match
  • Bash(gemini:*) - doesn't match

The entire permission system appears non-functional on Windows.

martymcenroe · 7 months ago

Write Tool Also Affected

Pattern matching is broken for the Write tool as well:

Configured permission:

"Write(C:\Users\mcwiz\Projects\**)"

Prompts appearing:

Do you want to create test_poetic_analyzer.py?
Do you want to create article-extractor.js?
Do you want to overwrite context.html?

Files are at paths like:

  • C:\Users\mcwiz\Projects\Aletheia-310\tests\unit\test_poetic_analyzer.py
  • C:\Users\mcwiz\Projects\Aletheia-106\extensions\chrome\article-extractor.js
  • C:\Users\mcwiz\Projects\Aletheia\docs\context.html

All paths clearly match C:\Users\mcwiz\Projects\**.

Also: Bash(mkdir:*) not matching mkdir -p /c/Users/mcwiz/Projects/Aletheia-310/docs/reports/310

---

Complete list of broken tools:

  • Read(**) - doesn't match
  • Write(C:\Users\mcwiz\Projects\**) - doesn't match
  • Edit(C:\Users\mcwiz\Projects\**) - doesn't match
  • Glob(**) - doesn't match
  • Search(**) - doesn't match
  • Bash(mkdir:*) - doesn't match
  • Bash(gemini:*) - doesn't match

Every tool type's permission matching is broken on Windows.

martymcenroe · 7 months ago

More Friction Events (Batch 3)

Continuing to document every permission prompt:

Edit prompt:

Do you want to make this edit to lambda_function.py?

Path: C:\Users\mcwiz\Projects\Aletheia-106\src\lambda_function.py
Pattern exists: Edit(C:\Users\mcwiz\Projects\**)

Bash cp prompt:

cp /c/Users/mcwiz/Projects/Aletheia-106/extensions/chrome/article-extractor.js /c/Users/mcwiz/Projects/Aletheia-106/extensions/firefox/article-extractor.js
Do you want to proceed?

Pattern exists: Bash(cp:*)

---

These are now 6 separate sessions all experiencing the same issue. Permission patterns exist but nothing matches.

User has had to manually approve ~50+ prompts in the last 2 hours alone.

martymcenroe · 7 months ago

More Friction Events (Batch 4)

git commit prompt:

git -C /c/Users/mcwiz/Projects/Aletheia commit -m "docs: normal cleanup..."
Do you want to proceed?

Pattern exists: Bash(git:*)

Write prompts (2x):

Do you want to create article-extractor.test.js?
Do you want to create full-article.spec.js?

Pattern exists: Write(C:\Users\mcwiz\Projects\**)

mkdir prompt:

mkdir -p /c/Users/mcwiz/Projects/Aletheia-106/docs/reports/106
Do you want to proceed?

Pattern exists: Bash(mkdir:*)

pip-audit prompt:

pip-audit --cache-dir=/tmp 2>&1

(No pattern - but wouldn't matter since nothing matches anyway)

---

Total manual approvals today: ~75+ across 8 sessions.

Every tool type remains broken on Windows.

martymcenroe · 7 months ago

Friction Batch 5 (End of Night)

curl prompt:

curl http://127.0.0.1:8000/
Do you want to proceed?

Pattern needed: Bash(curl:*) (exists in allowlist)

Write prompts (3x):

Do you want to create implementation-report.md?
Do you want to create pre-store-submit.sh?
Do you want to create stop-session-log.sh?

Pattern exists: Write(C:\Users\mcwiz\Projects\**)

---

Total manual approvals tonight: ~80+ across 10+ sessions.

Every single permission pattern is non-functional on Windows. The permission system provides zero value - it's pure friction with no security benefit since we approve everything anyway.

martymcenroe · 7 months ago

Friction Batch 6 (12 more events in 15 minutes)

User is trying to go to sleep. Agents keep triggering prompts.

Bash prompts:

chrome-webstore-upload --help 2>&1
CLAUDE_TOOL_INPUT_COMMAND="..." bash /c/Users/mcwiz/Projects/Aletheia/.claude/hooks/pre-store-submit.sh
git -C /c/Users/mcwiz/Projects/Aletheia commit -m "docs: normal cleanup..."
chmod +x /c/Users/mcwiz/Projects/Talos/.claude/tools/gemini-model-check.sh
/c/Users/mcwiz/Projects/Talos/.claude/tools/gemini-model-check.sh "$(cat ...)"

Patterns exist: Bash(git:*), Bash(chmod:*)

Write/Edit prompts (7x):

Do you want to create lld-review.txt.template?
Do you want to create implementation-review.txt.template?
Do you want to create issue-review.txt.template?
Do you want to create gemini-model-check.sh.template?
Do you want to overwrite project.json.example? (2x)
Do you want to make this edit to stop-session-log.sh?

Pattern exists: Write(C:\Users\mcwiz\Projects\**)

---

Running total tonight: ~95 manual approvals

This is across 12+ agent sessions. User cannot leave agents running unattended because EVERY operation requires manual approval.

The permission system is not just broken - it's actively hostile to productivity.

StudioLE · 7 months ago

I'm experiencing this on linux.

I have some markdown guidelines for claude stored in ~/.claude/guidelines/

I've given global permission to read these:

"Read(/var/home/USER/.claude/guidelines/**)",
"Read(~/.claude/guidelines/**)"

But it never matches and I'm constantly asked for read permission.

github-actions[bot] · 6 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

github-actions[bot] · 5 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.