eyaltoledano/claude-task-master · error
projectRoot is required for getGitRepositoryRoot
Error message
projectRoot is required for getGitRepositoryRoot
What it means
getGitRepositoryRoot runs 'git rev-parse --show-toplevel' with cwd=projectRoot to find the repository root. An empty projectRoot is rejected up front with this error because git cannot be executed relative to it. It is a fail-fast argument check.
Source
Thrown at packages/tm-core/src/common/utils/git-utils.ts:184
try {
const { stdout } = await execAsync(
'gh repo view --json name,owner,defaultBranchRef',
{ cwd: projectRoot }
);
return JSON.parse(stdout) as GitHubRepoInfo;
} catch (error) {
return null;
}
}
/**
* Get git repository root directory
*/
export async function getGitRepositoryRoot(
projectRoot: string
): Promise<string | null> {
if (!projectRoot) {
throw new Error('projectRoot is required for getGitRepositoryRoot');
}
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> {View on GitHub (pinned to c0c98d367c)
Solutions
- Pass a valid non-empty directory (process.cwd() is a sensible default)
- Fix the earlier resolution step that produced an empty root and re-run
- Guard the call: if (!projectRoot) return null; when root detection is best-effort
- Ensure the process actually starts inside or with a path to the project
Example fix
// before const root = await getGitRepositoryRoot(projectRoot); // projectRoot === '' // after const root = projectRoot ? await getGitRepositoryRoot(projectRoot) : await getGitRepositoryRoot(process.cwd());
Defensive patterns
Strategy: validation
Validate before calling
import { resolve } from 'path';
const root = resolve(projectRoot || process.cwd());
if (!root || root === '/') throw new Error('refusing to search for repo root from filesystem root'); Type guard
function isUsablePath(v: unknown): v is string {
return typeof v === 'string' && v.trim().length > 0 && v !== '/';
} Try / catch
try {
const repoRoot = await getGitRepositoryRoot(projectRoot);
} catch (err) {
if (err instanceof Error && err.message.includes('getGitRepositoryRoot')) {
console.error('No projectRoot supplied; retrying from process.cwd().');
return getGitRepositoryRoot(process.cwd());
}
throw err;
} Prevention
- Resolve the working directory at process start and store it in a single config object
- Never chain git-utils calls with values that earlier lookups may have returned as ''
- Prefer passing the resolved absolute path rather than raw user input
- Add a startup assertion that projectRoot is set for git-dependent commands
When it happens
Trigger: Calling getGitRepositoryRoot(undefined) or '' — usually a projectRoot variable that was never assigned before use, or config returning empty string.
Common situations: Bootstrapping code that calls root detection before resolving the working directory; CLI commands invoked with no --project-root flag and broken cwd detection; async chains where an earlier resolve() returned ''.
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
- 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/426c4db16f415619.
Report an issue: GitHub.