[BUG] Command deduplication drops commands on exFAT volumes due to inode precision loss

Resolved 💬 2 comments Opened Feb 23, 2026 by starkmichelsc Closed Mar 23, 2026

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

  1. Place a project on an exFAT volume
  2. Create 2+ files in .claude/commands/ with valid frontmatter
  3. Launch Claude Code from the project directory
  4. Only the first command file loads; the rest are skipped as duplicates
  5. 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).

View original on GitHub ↗

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