Cannot work with git worktrees due to directory restriction
Description
When working with git worktrees for feature development, Claude Code cannot navigate to worktree directories that are siblings to the main repository. This blocks a common development workflow.
Steps to Reproduce
- Have a main repository at
/path/to/project - Create git worktrees in
/path/to/project-worktrees/ - Start Claude Code in the main repository
- Try to navigate to worktree:
cd ../project-worktrees/feature-branch - Get error: "For security, Claude Code may only change directories to child directories of the allowed working directories"
Expected Behavior
Should be able to work with git worktrees, which are a standard git feature for isolated development.
Actual Behavior
Cannot navigate to worktree directories, making it impossible to use Claude Code with git worktrees.
Workarounds Attempted
- Adding directories via
/add-dirslash command - directories are added but navigation still blocked - Adding "../", "../project-worktrees" to ".claude/settings.json" and "./claude/settings.local.json"
- Starting from parent directory - not practical for project-specific work
Impact
This prevents using Claude Code for feature development workflows that rely on git worktrees for isolation. Worktrees are essential for:
- Working on multiple features simultaneously
- Keeping main branch clean
- Testing changes in isolation
Related Issues
- #1628 (general directory change request)
Suggested Solution
Either:
- Allow navigation to sibling directories that have been explicitly added via
/add-dir - Add specific support for git worktree directories
- Provide an explicit
/cdcommand as suggested in #1628
Additional Context: svelte-check Integration Issue
This limitation is particularly problematic when using TypeScript validation tools like svelte-check. The issue:
- svelte-check runs from main repository and detects changes in worktree directories
- Cannot configure svelte-check to ignore worktrees unless they're outside the main repo
- TypeScript errors from worktrees pollute main repo validation making it impossible to maintain clean TypeScript validation
Technical Analysis & Root Cause
I've reverse-engineered the cd protection implementation from the compiled CLI and identified the exact root cause and solution.
Code Location & Implementation
The issue is in the cd validation logic around line 1578 in the compiled CLI. Here's what I found:
Path Validation Function (decompiled as isChildDirectory):
function isChildDirectory(targetPath, allowedPath) {
let normalizedTarget = normalizePath(targetPath);
let normalizedAllowed = normalizePath(allowedPath);
if (\!normalizedTarget.startsWith(normalizedAllowed)) return false;
let nextChar = normalizedTarget[normalizedAllowed.length];
if (nextChar === undefined || nextChar === PATH_SEPARATOR) return true;
return false;
}
Working Directories Function (decompiled as getAllowedDirs):
function getAllowedDirs(permissionContext) {
return new Set([getCurrentWorkingDir(), ...permissionContext.additionalWorkingDirectories]);
}
Permission Check Function (decompiled as checkDirectoryPermission):
function checkDirectoryPermission(targetPath, permissionContext) {
return Array.from(getAllowedDirs(permissionContext)).some(allowedDir =>
isChildDirectory(targetPath, allowedDir)
);
}
CD Command Validation (decompiled as validateCdCommand):
function validateCdCommand(command, currentDir, rootDir, permissionContext) {
let subcommands = parseCommand(command.command);
for (let cmd of subcommands) {
let [baseCmd, ...args] = cmd.split(" ");
if (baseCmd === "cd" && args.length > 0) {
let targetDir = args.join(" ").replace(/^['"]|['"]$/g, "");
let resolvedPath = isAbsolute(targetDir) ? targetDir : resolve(currentDir, targetDir);
if (\!checkDirectoryPermission(resolvedPath, permissionContext)) {
return {
behavior: "ask",
message: `cd to '${resolvedPath}' was blocked. For security, Claude Code may only change directories to child directories of the allowed working directories for this session (including '${rootDir}').`
};
}
}
}
return { behavior: "allow", updatedInput: command };
}
The Bug
The isChildDirectory function only allows navigation to subdirectories of allowed working directories. However, directories added via /add-dir or additionalDirectories should be directly accessible, not just their children.
Current Logic: targetPath must be a child of an allowed directory
Needed Logic: targetPath can be a child of an allowed directory OR exactly match an allowed directory
The Fix
The checkDirectoryPermission function needs to be updated to allow both:
- Child directories of allowed working directories (current behavior)
- Direct navigation to additional working directories (missing behavior)
Proposed Fix:
function checkDirectoryPermission(targetPath, permissionContext) {
let allowedDirs = getAllowedDirs(permissionContext);
// Allow direct navigation to any additional working directory
if (allowedDirs.has(normalizePath(targetPath))) {
return true;
}
// Allow navigation to child directories (existing behavior)
return Array.from(allowedDirs).some(allowedDir =>
isChildDirectory(targetPath, allowedDir)
);
}
Verification
This analysis is based on decompiled code from the CLI binary. The variable names are logical replacements for minified names, but the logic flow is exactly as implemented.
The fix would allow cd to work properly with:
- Git worktree directories added via
/add-dir - Directories specified in
additionalDirectoriesconfiguration - CLI
--add-dirargument directories
While maintaining security by still restricting access to child directories of the current working directory only.
For the record this was all written by Claude, so I can't speak for the validity of the decompiled code or analysis (it seems flawed to me, because I do have a parent of a directory I'm trying to CD to in allowedDirectories). This is a very serious problem for me right now. I am also working on proposing a solution for the much larger problem in svelte-check, but it would be nice if these configuration options worked as expected within claude-code too.
I have the same issue - no matter how I try to define additionalDirectories, my orchestrator Claude Code instance (in /repos/main-worktree) cannot access the worktree directories in /worktrees/.
Found 1 possible duplicate issue:
- https://github.com/anthropics/claude-code/issues/2180
This issue will be automatically closed as a duplicate in 3 days.
- If your issue is a duplicate, please close it and 👍 the existing issue instead
- To prevent auto-closure, add a comment or 👎 this comment
🤖 Generated with Claude Code
Found 1 possible duplicate issue:
- https://github.com/anthropics/claude-code/issues/2180
This issue will be automatically closed as a duplicate in 3 days.
- If your issue is a duplicate, please close it and 👍 the existing issue instead
- To prevent auto-closure, add a comment or 👎 this comment
🤖 Generated with Claude Code
This request is for worktrees OUTSIDE of the working directory and is therefore not duplicated
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.
This is still a valid request that would benefit at least a few users.