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

  1. Pass a valid absolute project root string: await getWorktrees('/path/to/repo')
  2. Resolve the root before calling, e.g. const root = findProjectRoot() || process.cwd()
  3. 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

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


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/9d63ebc95796167e. Report an issue: GitHub.