Describe the bug
netlify dev fails to detect repository root in git worktrees
Description
The Netlify CLI fails to properly detect the repository root when running inside a git worktree. This causes netlify dev to fall back to the user's home directory as the cwd, breaking all relative path resolution in netlify.toml and preventing the CLI from fetching environment variables from Netlify.
Environment
- netlify-cli version: 23.13.3
- OS: macOS (darwin-arm64)
- Node: v22.21.1
Steps to Reproduce
-
Create a git worktree from an existing repository:
cd ~/git/my-repo
git worktree add ~/git/my-repo-worktree some-branch
-
Run netlify link in the worktree to link a site
-
Run netlify dev (or netlify dev --cwd ./apps/my-app for monorepos):
cd ~/git/my-repo-worktree
netlify dev
Expected Behavior
The CLI should detect ~/git/my-repo-worktree as the repository root and resolve all paths relative to it.
Actual Behavior
The CLI falls back to the user's home directory (/Users/username) as the cwd:
❯ Initial build environment
config: /Users/frank/git/knowfun-sandbox/apps/app-shareyourfans/netlify.toml
context: dev
cwd: /Users/frank # <-- Should be /Users/frank/git/knowfun-sandbox
This causes multiple failures:
-
Path resolution errors:
Base directory does not exist: /Users/frank/apps/app-shareyourfans
-
Environment variables not loaded:
Warning: Could not find account for project 'undefined' with account slug 'undefined'
-
Plugin resolution failures:
Plugin could not be found using local path: ../../netlify/plugins/netlify-plugin-bundle-env
-
Monorepo workspace detection fails:
[project.ts]: detectFrameworksInPath - undefined
Root Cause
The issue is in @netlify/config at lib/options/repository_root.js:
export const getRepositoryRoot = async function ({ repositoryRoot, cwd }) {
if (repositoryRoot !== undefined) {
return repositoryRoot;
}
const repositoryRootA = await findUp('.git', { cwd, type: 'directory' });
if (repositoryRootA === undefined) {
return cwd;
}
return dirname(repositoryRootA);
};
The findUp call specifies type: 'directory', but in a git worktree, .git is a file (not a directory) containing a pointer to the main repository:
# Contents of .git file in a worktree
gitdir: /Users/frank/git/my-repo/.git/worktrees/my-repo-worktree
Since findUp is looking for a directory and .git is a file, it never finds it and falls back to cwd — which through some other code path ends up as the user's home directory.
Suggested Fix
Modify the findUp call to find both files and directories by removing the type constraint:
const repositoryRootA = await findUp('.git', { cwd });
Or explicitly handle both cases:
const repositoryRootA = await findUp('.git', { cwd, type: 'directory' })
?? await findUp('.git', { cwd, type: 'file' });
Workaround
Users can patch their local installation:
sed -i '' "s/, type: 'directory'//" node_modules/netlify-cli/node_modules/@netlify/config/lib/options/repository_root.js
Or set the REPOSITORY_ROOT environment variable (though this alone doesn't fully fix the issue since monorepo detection still fails):
REPOSITORY_ROOT=/path/to/worktree netlify dev
Additional Context
Git worktrees are commonly used for:
- Working on multiple branches simultaneously
- Testing changes in isolation without stashing
- Running long builds while continuing development
This is a significant workflow that should be supported by the CLI.
Steps to reproduce
See Claude's writeup above
Configuration
[build]
publish = "dist/"
command = "npm run build"
edge_functions = "src/edge-functions/"
[build.environment]
NODE_VERSION = "22.18.0"
NPM_VERSION = "11.5.2"
NODE_SOURCEMAP = "true"
NODE_OPTIONS = "--max_old_space_size=4096"
[functions]
node_bundler = "esbuild"
directory = "src/functions/"
external_node_modules = ["@sentry/serverless", "@block65/webcrypto-web-push"]
deno_import_map = "deno-import-map.json"
[dev]
command = "vite"
targetPort = 5175
port = 8887
autoLaunch = false
[[plugins]]
package = "../../netlify/plugins/netlify-plugin-bundle-env"
[[redirects]]
from = "/service-worker.js.map"
to = "/index.html"
status = 404
force = true
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
for = "/dev-sw.js"
[headers.values]
Cache-Control = "no-cache"
[[headers]]
for = "/service-worker.js"
[headers.values]
Cache-Control = "no-cache"
Environment
System:
OS: macOS 26.2
CPU: (16) arm64 Apple M4 Max
Memory: 50.29 GB / 128.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.21.1 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 11.7.0 - /usr/local/bin/npm
pnpm: 7.27.0 - /usr/local/bin/pnpm
bun: 1.3.6 - /opt/homebrew/bin/bun
Deno: 2.4.5 - /Users/frank/.deno/bin/deno
Describe the bug
netlify devfails to detect repository root in git worktreesDescription
The Netlify CLI fails to properly detect the repository root when running inside a git worktree. This causes
netlify devto fall back to the user's home directory as thecwd, breaking all relative path resolution innetlify.tomland preventing the CLI from fetching environment variables from Netlify.Environment
Steps to Reproduce
Create a git worktree from an existing repository:
Run
netlify linkin the worktree to link a siteRun
netlify dev(ornetlify dev --cwd ./apps/my-appfor monorepos):Expected Behavior
The CLI should detect
~/git/my-repo-worktreeas the repository root and resolve all paths relative to it.Actual Behavior
The CLI falls back to the user's home directory (
/Users/username) as thecwd:This causes multiple failures:
Path resolution errors:
Environment variables not loaded:
Plugin resolution failures:
Monorepo workspace detection fails:
Root Cause
The issue is in
@netlify/configatlib/options/repository_root.js:The
findUpcall specifiestype: 'directory', but in a git worktree,.gitis a file (not a directory) containing a pointer to the main repository:Since
findUpis looking for a directory and.gitis a file, it never finds it and falls back tocwd— which through some other code path ends up as the user's home directory.Suggested Fix
Modify the
findUpcall to find both files and directories by removing thetypeconstraint:Or explicitly handle both cases:
Workaround
Users can patch their local installation:
Or set the
REPOSITORY_ROOTenvironment variable (though this alone doesn't fully fix the issue since monorepo detection still fails):Additional Context
Git worktrees are commonly used for:
This is a significant workflow that should be supported by the CLI.
Steps to reproduce
See Claude's writeup above
Configuration
[build]
publish = "dist/"
command = "npm run build"
edge_functions = "src/edge-functions/"
[build.environment]
NODE_VERSION = "22.18.0"
NPM_VERSION = "11.5.2"
NODE_SOURCEMAP = "true"
NODE_OPTIONS = "--max_old_space_size=4096"
[functions]
node_bundler = "esbuild"
directory = "src/functions/"
external_node_modules = ["@sentry/serverless", "@block65/webcrypto-web-push"]
deno_import_map = "deno-import-map.json"
[dev]
command = "vite"
targetPort = 5175
port = 8887
autoLaunch = false
[[plugins]]
package = "../../netlify/plugins/netlify-plugin-bundle-env"
[[redirects]]
from = "/service-worker.js.map"
to = "/index.html"
status = 404
force = true
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
for = "/dev-sw.js"
[headers.values]
Cache-Control = "no-cache"
[[headers]]
for = "/service-worker.js"
[headers.values]
Cache-Control = "no-cache"
Environment
System:
OS: macOS 26.2
CPU: (16) arm64 Apple M4 Max
Memory: 50.29 GB / 128.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.21.1 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 11.7.0 - /usr/local/bin/npm
pnpm: 7.27.0 - /usr/local/bin/pnpm
bun: 1.3.6 - /opt/homebrew/bin/bun
Deno: 2.4.5 - /Users/frank/.deno/bin/deno