{"record":{"id":"426c4db16f415619","repo":"eyaltoledano/claude-task-master","slug":"projectroot-is-required-for-getgitrepositoryroot","errorCode":null,"errorMessage":"projectRoot is required for getGitRepositoryRoot","messagePattern":"projectRoot is required for getGitRepositoryRoot","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/common/utils/git-utils.ts","lineNumber":184,"sourceCode":"\ttry {\n\t\tconst { stdout } = await execAsync(\n\t\t\t'gh repo view --json name,owner,defaultBranchRef',\n\t\t\t{ cwd: projectRoot }\n\t\t);\n\t\treturn JSON.parse(stdout) as GitHubRepoInfo;\n\t} catch (error) {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get git repository root directory\n */\nexport async function getGitRepositoryRoot(\n\tprojectRoot: string\n): Promise<string | null> {\n\tif (!projectRoot) {\n\t\tthrow new Error('projectRoot is required for getGitRepositoryRoot');\n\t}\n\n\ttry {\n\t\tconst { stdout } = await execAsync('git rev-parse --show-toplevel', {\n\t\t\tcwd: projectRoot\n\t\t});\n\t\treturn stdout.trim();\n\t} catch (error) {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get the default branch name for the repository\n */\nexport async function getDefaultBranch(\n\tprojectRoot: string\n): Promise<string | null> {","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/common/utils/git-utils.ts#L166-L202","documentation":"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.","triggerScenarios":"Calling getGitRepositoryRoot(undefined) or '' — usually a projectRoot variable that was never assigned before use, or config returning empty string.","commonSituations":"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 ''.","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"],"exampleFix":"// before\nconst root = await getGitRepositoryRoot(projectRoot); // projectRoot === ''\n// after\nconst root = projectRoot ? await getGitRepositoryRoot(projectRoot) : await getGitRepositoryRoot(process.cwd());","handlingStrategy":"validation","validationCode":"import { resolve } from 'path';\nconst root = resolve(projectRoot || process.cwd());\nif (!root || root === '/') throw new Error('refusing to search for repo root from filesystem root');","typeGuard":"function isUsablePath(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0 && v !== '/';\n}","tryCatchPattern":"try {\n  const repoRoot = await getGitRepositoryRoot(projectRoot);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('getGitRepositoryRoot')) {\n    console.error('No projectRoot supplied; retrying from process.cwd().');\n    return getGitRepositoryRoot(process.cwd());\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["git","argument-validation"],"backgroundTag":"missing-required-parameter","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}