[BUG] Windows: Skills/commands incorrectly flagged as duplicates due to partial NTFS FileId comparison

Resolved 💬 3 comments Opened Jan 5, 2026 by shiftynick Closed Jan 5, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

On Windows, Claude Code incorrectly skips loading skills and commands, reporting them as duplicates with "same inode already loaded" even though they are completely separate files in different directories. This appears to be caused by comparing only the file index portion of the NTFS FileId rather than the full identifier.When NTFS creates the first file in a new directory, it typically assigns file index 0000000000000002. If Claude Code only compares this portion (ignoring the directory identifier prefix), files across different directories appear to be duplicates.

What Should Happen?

All skills and commands with unique file paths and full FileIds should load successfully, regardless of matching file index portions. The deduplication logic should compare the complete NTFS FileId (or use full file path comparison) on Windows.

Error Messages/Logs

Debug log shows:
Skipping duplicate skill 'frontend-conventions' from projectSettings (same inode already loaded from projectSettings)
Skipping duplicate skill 'mockup-conversion' from projectSettings (same inode already loaded from projectSettings)
Skipping duplicate skill 'code-review' from projectSettings (same inode already loaded from projectSettings)
Loaded 2 unique skills (managed: 0, user: 0, project: 3, legacy commands: 2)

Despite all files having unique full FileIds (verified via fsutil file queryfileid):
backend-conventions\SKILL.md   → 0x0000000000008d510000000000000002
frontend-conventions\SKILL.md  → 0x0000000000008d530000000000000002
mockup-conversion\SKILL.md     → 0x0000000000008d550000000000000002
commands\code-review.md        → 0x0000000000008d4f0000000000000002

Note: The directory identifiers (first portion) are unique, but the file index (last portion 0000000000000002) is identical because each is the first file created in its directory.

Steps to Reproduce

Create a new project directory on Windows (NTFS)
Create the following structure with fresh directories and files:

.claude/
├── commands/
│ └── my-command.md
└── skills/
├── skill-one/
│ └── SKILL.md
├── skill-two/
│ └── SKILL.md
└── skill-three/
└── SKILL.md

Add valid frontmatter to each file:

skill-one/SKILL.md:
markdown---
name: Skill One
description: First test skill
---

Skill One

skill-two/SKILL.md:
markdown---
name: Skill Two
description: Second test skill
---

Skill Two

skill-three/SKILL.md:
markdown---
name: Skill Three
description: Third test skill
---

Skill Three

commands/my-command.md:
markdown---
description: Test command
---

My Command

Start Claude Code in the project directory
Check the debug log — only one skill loads, others are skipped as duplicates
Alternatively, run /skills and observe that not all skills appear

Note: This also occurs after git checkout or git pull because git recreates files with fresh file indices, often reassigning the same index (0000000000000002) to the first file in each directory.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

v2.0.76

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

Workaround: Force different file indices by deleting and recreating affected files with temp file creation in between:
powershell# fix-claude-fileids.ps1
$claudeDir = ".claude"

$filesToFix = @()
if (Test-Path "$claudeDir\skills") {
$filesToFix += Get-ChildItem -Path "$claudeDir\skills" -Recurse -Filter "SKILL.md" | Select-Object -ExpandProperty FullName
}
if (Test-Path "$claudeDir\commands") {
$filesToFix += Get-ChildItem -Path "$claudeDir\commands" -Filter "*.md" | Select-Object -ExpandProperty FullName
}

$counter = 0
foreach ($file in $filesToFix) {
$counter++
$content = Get-Content $file -Raw
Remove-Item $file -Force
$dir = Split-Path $file -Parent
1..($counter + 2) | ForEach-Object {
$tmp = Join-Path $dir "temp_$counter`_$_.tmp"
"x" | Out-File $tmp
Remove-Item $tmp
}
$content | Set-Content $file -NoNewline
}
This workaround must be re-run after every git checkout, git pull, or fresh clone.
Suggested fix: Compare the complete NTFS FileId or use full file path comparison rather than just the file index portion when deduplicating on Windows.

View original on GitHub ↗

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