eyaltoledano/claude-task-master · error

projectRoot is required for isGitRepository

Error message

projectRoot is required for isGitRepository

What it means

isGitRepository runs 'git rev-parse --git-dir' with projectRoot as the working directory. Since that is meaningless without a directory, the function first guards against an empty/undefined projectRoot and throws this error. It signals a programming mistake at the call site rather than a git problem.

Source

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

import { promisify } from 'util';

const execAsync = promisify(exec);

/**
 * GitHub repository information
 */
export interface GitHubRepoInfo {
	name: string;
	owner: { login: string };
	defaultBranchRef: { name: string };
}

/**
 * Check if the specified directory is inside a git repository
 */
export async function isGitRepository(projectRoot: string): Promise<boolean> {
	if (!projectRoot) {
		throw new Error('projectRoot is required for isGitRepository');
	}

	try {
		await execAsync('git rev-parse --git-dir', { cwd: projectRoot });
		return true;
	} catch (error) {
		return false;
	}
}

/**
 * Synchronous check if directory is in a git repository
 */
export function isGitRepositorySync(projectRoot: string): boolean {
	if (!projectRoot) {
		return false;
	}

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Pass a valid, non-empty absolute path as projectRoot (e.g. process.cwd() or the resolved project directory)
  2. Fix the upstream config resolution that produces an empty/undefined root
  3. Default the argument at the call site: projectRoot || process.cwd()
  4. Add an early assertion in your own code so the empty root is caught with a clearer message

Example fix

// before
const inRepo = await isGitRepository(config.projectRoot);
// after
if (!config.projectRoot) throw new Error('Project root not configured');
const inRepo = await isGitRepository(config.projectRoot || process.cwd());
Defensive patterns

Strategy: validation

Validate before calling

import { isAbsolute } from 'path';
import { existsSync } from 'fs';
function hasProjectRoot(root) {
  return typeof root === 'string' && root.length > 0 && isAbsolute(root) && existsSync(root);
}
if (!hasProjectRoot(projectRoot)) throw new Error('projectRoot must be a non-empty existing directory');

Type guard

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

Try / catch

try {
  const inRepo = await isGitRepository(projectRoot);
} catch (err) {
  if (err instanceof Error && err.message.includes('projectRoot is required')) {
    console.error('projectRoot was not set; pass the project directory path.');
    return false;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling isGitRepository(undefined) or isGitRepository('') — typically when a config value or CLI option supplying the project root was never set.

Common situations: Calling the utility before project root detection has run; tests that forget to pass a root; config loaders that return an empty root for an uninitialized project; wiring a promise result that resolves to '' on failure.

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/5c2b15609ee68dc7. Report an issue: GitHub.