eyaltoledano/claude-task-master · error

projectRoot is required for getDefaultBranch

Error message

projectRoot is required for getDefaultBranch

What it means

getDefaultBranch resolves the repository's default branch, first via gh CLI/GitHub info and falling back to git symbolic-ref, executing in projectRoot. An empty projectRoot is rejected by the guard before any command runs. It is a fail-fast argument check for a function usually reached through currentBranch/defaultBranch helpers.

Source

Thrown at packages/tm-core/src/common/utils/git-utils.ts:204

	try {
		const { stdout } = await execAsync('git rev-parse --show-toplevel', {
			cwd: projectRoot
		});
		return stdout.trim();
	} catch (error) {
		return null;
	}
}

/**
 * Get the default branch name for the repository
 */
export async function getDefaultBranch(
	projectRoot: string
): Promise<string | null> {
	if (!projectRoot) {
		throw new Error('projectRoot is required for getDefaultBranch');
	}

	try {
		// Try to get from GitHub first (if gh CLI is available)
		if (await isGhCliAvailable(projectRoot)) {
			const repoInfo = await getGitHubRepoInfo(projectRoot);
			if (repoInfo && repoInfo.defaultBranchRef) {
				return repoInfo.defaultBranchRef.name;
			}
		}

		// Fallback to git remote info (support non-origin remotes)
		const remotesRaw = await execAsync('git remote', { cwd: projectRoot });
		const remotes = remotesRaw.stdout.trim().split('\n').filter(Boolean);
		if (remotes.length > 0) {
			const primary = remotes.includes('origin') ? 'origin' : remotes[0];
			// Parse `git remote show` (preferred)
			try {

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Pass a valid repository path: getDefaultBranch('/path/to/project')
  2. Default to process.cwd() at the call site
  3. Repair config/CLI parsing so projectRoot is always populated
  4. Guard upstream helpers to short-circuit with null when root is missing

Example fix

// before
const def = await getDefaultBranch(root); // root undefined
// after
const def = root ? await getDefaultBranch(root) : null;
Defensive patterns

Strategy: validation

Validate before calling

if (!projectRoot || typeof projectRoot !== 'string') {
  throw new Error('getDefaultBranch needs a valid projectRoot');
}
// then handle both null (unknown default) and a value:
const defaultBranch = await getDefaultBranch(projectRoot);

Type guard

function isNonEmptyRoot(v: unknown): v is string {
  return typeof v === 'string' && v.length > 0;
}

Try / catch

try {
  const def = await getDefaultBranch(projectRoot);
} catch (err) {
  if (err instanceof Error && err.message.includes('getDefaultBranch')) {
    console.error('projectRoot missing; assuming "main".');
    return 'main';
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling getDefaultBranch(undefined) or ''; also triggered indirectly when isOnDefaultBranch or wrapper helpers forward an empty root.

Common situations: Automation where the project root option is optional and unset; tests stubbing config with partial objects; downstream propagation of an earlier failed root lookup.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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