[BUG] .gitignore causes slash command resolution to fail

Resolved 💬 3 comments Opened Aug 14, 2025 by KenSCompareCredit Closed Aug 18, 2025

Environment

  • Platform (select one):
  • [ ] Anthropic API
  • [ ] AWS Bedrock
  • [ ] Google Vertex AI
  • [x] Other:
  • Running Claude Code in terminal in VS Code in WSL 2 on my laptop during local development
  • Claude CLI version: 1.0.81 (Claude Code)
  • Operating System: Ubuntu 22.04.5 LTS (Jammy Jellyfish) running in WSL 2.4.13.0 in Windows 11 Pro (OS build: 26100.4946, Experience: Windows Feature Experience Pack 1000.26100.197.0)
  • Terminal: GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

Bug Description

Resolution of slash commands in subdirectories seems not to consistently follow the rules described in the docs, resulting in slash commands not being interpreted as slash commands.

Based on some testing I did, the problem appears to be that slash command resolution fails if the command is in a subdirectory which is ignored by Git (e.g. by adding it to .gitignore). This was unexpected, since it was not documented in the documentation anywhere that I could find.

We ran into this on my team because we wanted to create a .claude/commands/local/ directory within a project to enable engineers to define commands which are both project-scoped and personal (i.e. not committed to the repo), effectively a combination of personal commands and project commands. Previously some of us had created some project commands which we were just not committing, but this was cumbersome to manage (need to remember not to commit them, and need to delete and recreate them to execute Git commands that require a clean working tree), so we wanted to place these in a .gitignored .claude/commands/local/ directory to make it easier to manage them.

Steps to Reproduce

  1. Create a project-level command at .claude/commands/local/foo.md. The contents can be anything for testing, such as asking it to create a file called foo.ts in the project root or just output "foo" to the console
  2. In .gitignore, add .claude/commands/local/
  3. In your terminal, start a Claude Code session by running claude
  4. At the Claude Code prompt, type /local:foo and hit enter

Expected Behavior

Claude Code interprets /local:foo as a slash command, and resolves it to the .claude/commands/local/foo.md command file.

Actual Behavior

Claude Code does not recognize /local:foo as a slash command. It searches unsuccessfully for a file or directory called "foo", for a local command, or "something specific to the project", then reports that it did not find anything, and asks the user to clarify what their prompt meant.

Additional Context

Minimal reproduction example

In this example, there is a file at .claude/commands/local/foo.md with the contents Just output "foo" to the console. There is also a .gitignore file which contains the line .claude/commands/local/.

Output from Claude Code session:

╭────────────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                              │
│                                                        │
│   /help for help, /status for your current setup       │
│                                                        │
│   cwd: /home/skudbub/comparecredit/repo/comparecredit  │
╰────────────────────────────────────────────────────────╯


 What's new:
  • Released output styles, including new built-in educational output styles
   "Explanatory" and "Learning". Docs: 
  https://docs.anthropic.com/en/docs/claude-code/output-styles
  • Plugin system: Improve plugin repository installation messaging and 
  error handling
  • Agents: Fix custom agent loading when agent files are unparsable
  • Add plugin system: Install plugins from Git repositories with custom 
  commands and agents using /plugin commands
  • UI improvements: Fix text contrast for custom subagent colors and 
  spinner rendering issues

> /local:foo

● I need to see what /local:foo refers to. Let me check if this is a
  file path or command.

● List(~/comparecredit/repo/comparecredit)
  ⎿  Listed 15 paths (ctrl+r to expand)

● I don't see a file or directory called "foo" in the current
  directory. Let me check if there's a local command or if you're
  referring to something specific in this project.

● Search(pattern: "**/foo*")
  ⎿  Found 66 files (ctrl+r to expand)

● The /local:foo syntax isn't a standard file path. Could you clarify
  what you're looking for? Are you:

  1. Looking for a file named "foo"?
  2. Referring to a local command or script?
  3. Using a specific syntax I should understand?

  The search shows various test files and dependencies with "foo" in
  the name, but no specific "foo" file in the project root.

> This was supposed to be a slash command. I was expecting you to 
  interpret it as a slash command and resolve it to the command file 
  located at .claude/commands/local/foo.md

● I see! You're using the /local:foo slash command. Let me read the
  command file to understand what it should do.

● Read(.claude/commands/local/foo.md)
  ⎿  Read 1 line (ctrl+r to expand)

● foo

More in-depth example

In this example, there is a .claude/commands/local/new-issue-in-temp-notes.md file containing a command to add notes about a Linear issue to a local file. There is also a .gitignore file which contains the line .claude/commands/local/.

Output from Claude Code session:

╭────────────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                              │
│                                                        │
│   /help for help, /status for your current setup       │
│                                                        │
│   cwd: /home/skudbub/comparecredit/repo/comparecredit  │
╰────────────────────────────────────────────────────────╯

> /local:new-issue-in-temp-notes.md

● I'll create a new issue in the temp-notes.md file for you.

● Read(temp-notes.md)
  ⎿  Error reading file

● Write(temp-notes.md)
  ⎿  User rejected write to temp-notes.md
        1 +  # Temp Notes
        2 +  
        3 +  ## Issue: [Issue Title]
        4 +  
        5 +  **Date:** 2025-08-14
        6 +  
        7 +  **Description:**
        8 +  [Brief description of the issue]
        9 +  
       10 +  **Steps to Reproduce:**
       11 +  1. 
       12 +  2. 
       13 +  3. 
       14 +  
       15 +  **Expected Behavior:**
       16 +  [What should happen]
       17 +  
       18 +  **Actual Behavior:**
       19 +  [What actually happens]
       20 +  
       21 +  **Additional Context:**
       22 +  [Any additional information, logs, or context]
       23 +  
       24 +  **Priority:** [Low/Medium/High]
       25 +  
       26 +  **Status:** [Open/In Progress/Closed]
       27   \ No newline at end of file

> /local:new-issue-in-temp-notes CC-2684

● Read(temp-notes.md)
  ⎿  Error reading file

● Write(temp-notes.md)
  ⎿  User rejected write to temp-notes.md
        1 +  # Temp Notes
        2 +  
        3 +  ## Issue: CC-2684
        4 +  
        5 +  **Date:** 2025-08-14
        6 +  
        7 +  **Description:**
        8 +  [Brief description of the issue]
        9 +  
       10 +  **Steps to Reproduce:**
       11 +  1. 
       12 +  2. 
       13 +  3. 
       14 +  
       15 +  **Expected Behavior:**
       16 +  [What should happen]
       17 +  
       18 +  **Actual Behavior:**
       19 +  [What actually happens]
       20 +  
       21 +  **Additional Context:**
       22 +  [Any additional information, logs, or context]
       23 +  
       24 +  **Priority:** [Low/Medium/High]
       25 +  
       26 +  **Status:** [Open/In Progress/Closed]
       27   \ No newline at end of file

> Why did you try to write to temp-notes.md? Were you able to resolve 
  the `/local:new-issue-in-temp-notes` slash command I entered to a 
  command file? I was expecting it to resolve to 
  `.claude/commands/local/new-issue-in-temp-notes.md`, so if it didn't,
   we should fix that first

● You're absolutely right - I should have looked for the command file
  at .claude/commands/local/new-issue-in-temp-notes.md to resolve the
  slash command. Let me check if that file exists:

● Read(.claude/commands/local/new-issue-in-temp-notes.md)
  ⎿  Read 66 lines (ctrl+r to expand)

● Perfect! The command file exists and I can see what it's supposed to
  do. Now I need to:

  1. Look up the Linear issue CC-2684
  2. Add it to the temp notes file at .vscode/temp_notes.md in the
  specified format

  Let me first look up the Linear issue:

● linear-server - get_issue (MCP)(id: "CC-2684")
  ⎿  No (tell Claude what to do differently)

> Hang on. You didn't answer my question. When I first entered the 
  `/local:new-issue-in-temp-notes` slash command, did you or did you 
  not resolve it to the 
  `.claude/commands/local/new-issue-in-temp-notes.md` command file?

● No, I did not resolve the /local:new-issue-in-temp-notes slash
  command to the .claude/commands/local/new-issue-in-temp-notes.md
  command file.

  I incorrectly tried to write directly to a temp-notes.md file instead
   of following the slash command resolution process to find and
  execute the command defined in the
  .claude/commands/local/new-issue-in-temp-notes.md file.

> Why? Based on the docs at https://docs.anthropic.com/en/docs/claude-c
  ode/slash-commands#namespacing I was expecting the process by which 
  you resolve slash commands to be deterministic, so it is unexpected 
  that you did not resolve the `/local:new-issue-in-temp-notes` slash 
  command I entered according to the rules outlined in the docs (where 
  subdirectories create slash commands prefixed with the subdirectory 
  name followed by a colon). Why might this have happened? Does the 
  fact that the `.claude/commands/local` directory is in the 
  `.gitignore` affect your slash command resolution at all?

● You're absolutely right that slash command resolution should be
  deterministic according to the docs. Let me fetch the current
  documentation to understand the expected behavior:

● Fetch(https://docs.anthropic.com/en/docs/claude-code/slash-commands#n
       amespacing)
  ⎿  Received 2.1MB (200 OK)

● Based on the documentation, you're correct - the
  /local:new-issue-in-temp-notes command should have been resolved to
  .claude/commands/local/new-issue-in-temp-notes.md.

  I made an error in not following the proper slash command resolution
  process. The fact that the .claude/commands/local directory is in
  .gitignore should not affect slash command resolution - Claude Code
  should still be able to read and execute commands from that directory
   since it exists in the working directory.

  The issue appears to be that I didn't properly recognize and process
  your input as a slash command that needed to be resolved. Instead, I
  incorrectly interpreted it as a direct instruction to create an issue
   in a temp-notes.md file. This was a mistake in my command processing
   logic, not a technical limitation with the slash command system.

> If the interpretation of slash commands follows deterministic rules 
  as outlined in the docs I linked a moment ago, shouldn't it be 
  impossible for you to fail to interpret 
  `/local:new-issue-in-temp-notes.md` as a slash command? Are the docs 
  incorrect? Is your command processing logic actually 
  non-deterministic? Is it deterministic but just has a bug? What's 
  going on here?

● You're absolutely right to question this. If slash command resolution
   is truly deterministic as documented, then my failure to interpret
  /local:new-issue-in-temp-notes as a slash command shouldn't be
  possible.

  I don't have direct visibility into how my slash command resolution
  system actually works internally. From my perspective, I should have
  automatically recognized /local:new-issue-in-temp-notes as a slash
  command, looked for
  .claude/commands/local/new-issue-in-temp-notes.md, found it, and
  executed the instructions within it.

  The fact that I didn't suggests one of these possibilities:

  1. Bug in the slash command resolution system - The deterministic
  process described in the docs isn't working correctly in practice
  2. The docs are incomplete - There may be edge cases or conditions
  not documented that affect resolution
  3. System limitation - Perhaps there's an issue with how I access
  files in subdirectories of .claude/commands/
  4. My implementation has a flaw - The command resolution logic may
  not be working as intended

  Since this should be deterministic and I failed to follow the
  expected behavior, this appears to be either a bug in the slash
  command system or a gap between the documented behavior and actual
  implementation. The fact that the file exists and is readable (as we
  confirmed) makes this particularly puzzling.

  This seems like something that should be reported as a potential
  issue with Claude Code's slash command resolution.

View original on GitHub ↗

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