[BUG] Command deduplication drops commands on exFAT volumes due to inode precision loss
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
Custom slash commands in .claude/commands/ are deduplicated by inode number. On exFAT volumes, macOS synthesizes inode numbers near 2^64 (~18446744073709508XXX). When Node.js reads these via fs.stat(), they exceed Number.MAX_SAFE_INTEGER (2^53 - 1) and lose precision — all distinct inodes round to the same JavaScript Number.
This causes the deduplication logic to treat every command file as a duplicate of the first one loaded. Only 1 of N commands survives.
Debug log output:
Loading skills from: managed=..., user=..., project=[]
[STARTUP] Loading commands and agents...
Skipping duplicate file '.claude/commands/commands.md' from projectSettings (same inode already loaded from projectSettings)
Skipping duplicate file '.claude/commands/ralph-monitor.md' from projectSettings (same inode already loaded from projectSettings)
Skipping duplicate file '.claude/commands/scene-check.md' from projectSettings (same inode already loaded from projectSettings)
...
Deduplicated 12 files in commands (same inode via symlinks or hard links)
Loaded 6 unique skills (6 unconditional, 0 conditional, managed: 0, user: 0, project: 0, additional: 0, legacy commands: 6)
13 command files exist, 12 are dropped as "duplicates."
Root Cause
// All 13 files have distinct inodes on disk:
// 18446744073709508690, 18446744073709508681, 18446744073709508699, ...
//
// But Number() truncates them all to the same value:
const inodes = [18446744073709508690, 18446744073709508681, 18446744073709508699];
new Set(inodes.map(Number)).size; // → 1
// They all become 18446744073709509000
Number.MAX_SAFE_INTEGER is 9007199254740991. exFAT synthetic inodes exceed this by ~2x, so all precision in the lower bits is lost.
What Should Happen?
All command files with distinct inodes should be loaded, regardless of inode magnitude.
Suggested Fix
Use string comparison or BigInt for inode deduplication:
// Instead of comparing stat.ino as Number:
const key = String(stat.ino);
// or
const key = BigInt(stat.ino);
Steps to Reproduce
- Place a project on an exFAT volume
- Create 2+ files in
.claude/commands/with valid frontmatter - Launch Claude Code from the project directory
- Only the first command file loads; the rest are skipped as duplicates
- Confirm in debug log: "Deduplicated N files in commands (same inode via symlinks or hard links)"
Environment
- Claude Code Version: 2.1.50
- Platform: macOS (Apple Silicon)
- Filesystem: exFAT on external volume (
/Volumes/...) - Node: v24.x
Claude Model
Opus
Is this a regression?
I don't know
Platform
macOS
Operating System
macOS 15 (Darwin 24.6.0)
Terminal/Shell
zsh (standalone CLI)
Additional Information
User-level commands at ~/.claude/commands/ on APFS are unaffected — APFS inodes are well within MAX_SAFE_INTEGER. The bug is specific to filesystems that generate large synthetic inode numbers (exFAT, FAT32, possibly NFS/SMB mounts).
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗