Permission patterns with ~ paths don't match when paths are converted to relative

Resolved 💬 3 comments Opened Dec 27, 2025 by stepankuzmin Closed Dec 31, 2025

Bug Description

Permission patterns using ~ paths (e.g., Write(~/.claude/**)) don't work because the permission system converts absolute paths to relative paths before matching.

Steps to Reproduce

  1. Add Write(~/.claude/**) to global settings.json permissions
  2. From ~/.claude directory, attempt to write to ~/.claude/handoffs/test.md
  3. Permission prompt appears asking for Write(handoffs/test.md)

Expected Behavior

Write(~/.claude/**) should match any write to files inside ~/.claude/, regardless of current working directory.

Actual Behavior

  • The permission prompt shows a relative path: Write(handoffs/test.md)
  • The pattern ~/.claude/** doesn't match handoffs/test.md because one is absolute-style and one is relative
  • Even explicit Write(~/.claude/handoffs/**) doesn't match

Environment

  • macOS
  • Claude Code CLI
  • Pattern tested in both global settings.json and slash command allowed-tools

Analysis

The permission system appears to:

  1. Take the absolute path from the tool call (e.g., /Users/user/.claude/handoffs/test.md)
  2. Convert it to relative (from cwd): handoffs/test.md
  3. Match against patterns literally

This means ~/.claude/** can never match because the path being checked doesn't start with ~/.claude/.

Suggested Fix

Either:

  1. Normalize both pattern and path to absolute before comparing
  2. Expand ~ in patterns and compare against absolute paths
  3. Don't convert paths to relative before matching

Workaround Attempted

  • Write(~/.claude/**) - doesn't work
  • Write(~/.claude/handoffs/**) - doesn't work
  • Write(handoffs/**) - only works when cwd is ~/.claude
  • Write(**/handoffs/**) - untested, may work but overly permissive

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗