Glob tool does not follow symbolic links
Summary
The Glob tool does not traverse symbolic links to directories. When a symlink points to a directory containing files, patterns like symlink/* or symlink/**/* return "No files found".
Reproduction Steps
- Create a directory with files:
``bash``
mkdir -p /tmp/test-dir
echo "test" > /tmp/test-dir/file.txt
- Create a symlink in your project:
``bash``
ln -sf /tmp/test-dir symlink
- Try to glob through the symlink:
Glob pattern: symlink/*→ No files foundGlob pattern: symlink/*.txt→ No files foundGlob pattern: symlink(the symlink itself) → No files found
- Compare with direct path:
Glob pattern: * in /tmp/test-dir→ Finds file.txt ✓
- Compare with Read tool:
Read: <project>/symlink/file.txt→ Works correctly ✓
Expected Behavior
Glob should follow symlinks by default (similar to find -L, standard glob libraries, or ripgrep's default behavior), or provide an option to enable symlink following.
Actual Behavior
- Glob ignores symlinked directories entirely
- Cannot match files inside symlinked directories
- Cannot even match the symlink name itself as a pattern
Use Case
In GitHub Actions workflows (e.g., claude-code-action), we create symlinks to temp directories containing contextual data (JIRA tickets, Confluence pages). The CLAUDE.md instructions reference these symlinked paths with glob patterns, which fail silently:
# In GitHub Actions workflow
- name: Create guideline symlinks
run: |
ln -sf "$RUNNER_TEMP/atlassian" 'atlassian'
<!-- In CLAUDE.md -->
Check if "atlassian" directory exists. If so, read atlassian/*.xml files...
This pattern works for the Read tool but fails for Glob, creating an inconsistency between tools.
Suggested Solution
Either:
- Follow symlinks by default (most intuitive, matches other tools)
- Add a
followSymlinks: trueparameter to the Glob tool - Document the limitation clearly
Environment
- Claude Code CLI (latest via npm)
- Linux (Ubuntu)
- Also likely affects macOS
Showing cached comments. Read the full discussion on GitHub ↗
8 Comments
This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.
Yes this still occurs, please fix it provide a way for us to (like allowing us to rewrite arguments and pass glob arg to follow symlinks)
This is still relevant.
This is still relevant
Still seeing this — and dropping the root cause for whoever picks it up. We hit it while building our own agent tooling on top of the SDK.
The Glob tool is implemented on top of
ripgrep --files --glob <pattern> --no-ignore --hidden. By defaultripgrepdoes not traverse symlinks; it would need the-L/--followflag, which the CLI does not pass. Likely candidate to patch is the file that builds thergargv for the Glob tool (something likesrc/utils/glob.tsin earlier layouts).One-line repro (no Claude Code involved):
Same delta as
findvsfind -L. The fix is either passing-Lby default, or exposing it as an opt-in — consistent withRead, which already resolves through symlinks.Workaround for wrappers around the CLI: replace symlinks with hard-links. Hard-links share the inode with the source, so
ripgrepsees them as regular files — verified working. (Doesn't help the GitHub Actions /CLAUDE.mduse case from the original report, since cross-filesystem hard-links fail withEXDEV.)/cc @bcherny @ashwin-ant @claude — flagging in case useful. (Yes, tagging Claude too — felt fitting. 🙃)
Another workaround is to install ripgrep on the system, set
USE_BUILTIN_RIPGREP=0and makeRIPGREP_CONFIG_PATHpoint to a file with--followas the content.Yes this still occurs, please fix it
hacky workaround I have, register a PostToolUse on Glob, if no files found, check if path is symlink, if it is, Glob the target and return contents using updatedToolOutput