claude-code - 💡(How to fix) Fix enforce-specs: exclude patterns don't match absolute file paths [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#46258Fetched 2026-04-11 06:25:04
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
labeled ×3commented ×1

Root Cause

In .claude/hooks/context/enforce-specs.cjs, the matchGlob function normalizes file paths by removing the leading slash: path.replace(/^\//, ''). However, it then attempts to match this absolute path against glob patterns that are relative paths.

When a path like /Users/luisladino/Repositories/Personal/my-brain/projects/handshake/reviews/... is normalized, it becomes Users/luisladino/... (still an absolute path without the leading slash). This is compared against the pattern projects/**, which compiles to the regex ^projects/.*.

Since the normalized path doesn't START with projects/, it fails to match, even though it contains that path component. The applies_to patterns work because they use **/*.md which compiles to .*\.md and matches anywhere in the path.

Code Example

[BLOCKED] Read all required specs before editing.

---

let matchPath = filePath;
if (filePath.includes('/projects/')) {
  matchPath = filePath.split('/projects/')[1];
  matchPath = 'projects/' + matchPath;
}
RAW_BUFFERClick to expand / collapse

Problem

The enforce-specs hook is blocking edits to files in project-specific directories (e.g., projects/handshake/reviews/) even though .claude/specs/architecture/project-structure.md explicitly excludes those paths with the pattern projects/**.

When attempting to write or edit files under projects/, the hook fails with:

[BLOCKED] Read all required specs before editing.

But the specs file clearly marks projects/ as a project-specific location (outside kit-owned files), so these paths should not trigger spec-read enforcement.

Root Cause

In .claude/hooks/context/enforce-specs.cjs, the matchGlob function normalizes file paths by removing the leading slash: path.replace(/^\//, ''). However, it then attempts to match this absolute path against glob patterns that are relative paths.

When a path like /Users/luisladino/Repositories/Personal/my-brain/projects/handshake/reviews/... is normalized, it becomes Users/luisladino/... (still an absolute path without the leading slash). This is compared against the pattern projects/**, which compiles to the regex ^projects/.*.

Since the normalized path doesn't START with projects/, it fails to match, even though it contains that path component. The applies_to patterns work because they use **/*.md which compiles to .*\.md and matches anywhere in the path.

Reproduction

  1. Create or edit a file under projects/handshake/reviews/
  2. Observe: enforce-specs hook blocks the edit even though specs file excludes projects/**
  3. Expected: File should be editable without triggering spec-read enforcement

Proposed Solutions

Option A: Strip path down to project root

Before matching against glob patterns, detect if the path contains a project root and extract only the relative portion from there:

let matchPath = filePath;
if (filePath.includes('/projects/')) {
  matchPath = filePath.split('/projects/')[1];
  matchPath = 'projects/' + matchPath;
}

Then match matchPath against the glob patterns. This ensures paths like projects/... match the projects/** exclude pattern correctly.

Option B: Use glob matching library with proper path handling

Replace the custom matchGlob implementation with a robust glob library (e.g., minimatch or micromatch) that correctly handles both absolute and relative paths by design.

Impact

Currently, any project-specific work that requires file creation or editing in the projects/ directory triggers unnecessary spec-enforcement. This affects review workflows, testing, and documentation tasks that fall outside the kit scope.

extent analysis

TL;DR

The enforce-specs hook can be fixed by modifying the matchGlob function to correctly handle absolute paths or by using a robust glob matching library.

Guidance

  • Verify the issue by checking the enforce-specs.cjs file and the .claude/specs/architecture/project-structure.md file to ensure the projects/** pattern is correctly defined.
  • Consider implementing Option A by modifying the matchGlob function to extract the relative path from the project root before matching against glob patterns.
  • Alternatively, explore Option B by replacing the custom matchGlob implementation with a robust glob library like minimatch or micromatch.
  • Test the changes by creating or editing a file under projects/handshake/reviews/ to ensure the enforce-specs hook no longer blocks the edit.

Example

// Example of modified matchGlob function (Option A)
let matchPath = filePath;
if (filePath.includes('/projects/')) {
  matchPath = filePath.split('/projects/')[1];
  matchPath = 'projects/' + matchPath;
}
// Then match matchPath against the glob patterns

Notes

The current implementation of the matchGlob function may not work correctly for all file paths, and using a robust glob library can provide a more reliable solution.

Recommendation

Apply workaround by implementing Option B: Use a glob matching library with proper path handling, as it provides a more robust and reliable solution.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix enforce-specs: exclude patterns don't match absolute file paths [1 comments, 2 participants]