eyaltoledano/claude-task-master · error
projectRoot is required for getWorktrees
Error message
projectRoot is required for getWorktrees
What it means
getWorktrees() lists all git worktrees for a repository by running 'git worktree list --porcelain' with cwd set to projectRoot. Before doing anything it guards against a missing/empty projectRoot, throwing this error because a working directory is mandatory for the child git process.
Source
Thrown at packages/tm-core/src/common/utils/git-utils.ts:350
}
/**
* Git worktree information
*/
export interface GitWorktree {
path: string;
branch: string | null;
head: string;
}
/**
* Get list of all git worktrees
*/
export async function getWorktrees(
projectRoot: string
): Promise<GitWorktree[]> {
if (!projectRoot) {
throw new Error('projectRoot is required for getWorktrees');
}
try {
const { stdout } = await execAsync('git worktree list --porcelain', {
cwd: projectRoot
});
const worktrees: GitWorktree[] = [];
const lines = stdout.trim().split('\n');
let current: Partial<GitWorktree> = {};
for (const line of lines) {
if (line.startsWith('worktree ')) {
// flush previous entry if present
if (current.path) {
worktrees.push({
path: current.path,
branch: current.branch || null,View on GitHub (pinned to c0c98d367c)
Solutions
- Pass a valid absolute project root string: await getWorktrees('/path/to/repo')
- Resolve the root before calling, e.g. const root = findProjectRoot() || process.cwd()
- Check the config source that feeds the worktrees() wrapper so projectRoot is populated
Example fix
// before
await getWorktrees(config.projectRoot);
// after
const root = config.projectRoot || findProjectRoot() || process.cwd();
if (!root) throw new Error('Unable to resolve project root');
await getWorktrees(root); Defensive patterns
Strategy: validation
Validate before calling
if (!projectRoot || typeof projectRoot !== 'string') throw new Error('projectRoot must be a non-empty string before calling getWorktrees'); Type guard
function hasProjectRoot(root: unknown): root is string {
return typeof root === 'string' && root.trim().length > 0;
} Try / catch
try {
const worktrees = await getWorktrees(root);
} catch (err) {
if (err.message.includes('projectRoot is required')) {
root = findProjectRoot() || process.cwd();
return retryGetWorktrees(root);
}
throw err;
} Prevention
- Resolve and cache the project root once at app startup
- Never pass config values straight through without an emptiness check
- Prefer findProjectRoot()/process.cwd() fallbacks over raw config
When it happens
Trigger: Calling getWorktrees(''), getWorktrees(undefined as any), getWorktrees(null as any), or passing an empty/undefined projectRoot — typically from the worktrees() wrapper that forwards an unset configuration value.
Common situations: Config file missing a project root; calling from code that never resolved the project root (e.g. running outside a detected repo and skipping the fallback to process.cwd()); refactored callers passing options objects instead of a string.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- projectRoot is required for isGitRepository
- projectRoot is required for getCurrentBranch
- projectRoot is required for getLocalBranches
- projectRoot is required for getRemoteBranches
- projectRoot is required for getGitHubRepoInfo
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/9d63ebc95796167e.
Report an issue: GitHub.