{"record":{"id":"e146380d852e2e25","repo":"eyaltoledano/claude-task-master","slug":"projectroot-is-required-for-getgithubrepoinfo","errorCode":null,"errorMessage":"projectRoot is required for getGitHubRepoInfo","messagePattern":"projectRoot is required for getGitHubRepoInfo","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/common/utils/git-utils.ts","lineNumber":163,"sourceCode":" */\nexport async function isGhCliAvailable(projectRoot?: string): Promise<boolean> {\n\ttry {\n\t\tconst options = projectRoot ? { cwd: projectRoot } : {};\n\t\tawait execAsync('gh auth status', options);\n\t\treturn true;\n\t} catch (error) {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get GitHub repository information using gh CLI\n */\nexport async function getGitHubRepoInfo(\n\tprojectRoot: string\n): Promise<GitHubRepoInfo | null> {\n\tif (!projectRoot) {\n\t\tthrow new Error('projectRoot is required for getGitHubRepoInfo');\n\t}\n\n\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","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/common/utils/git-utils.ts#L145-L181","documentation":"getGitHubRepoInfo shells out to 'gh repo view --json name,owner,defaultBranchRef' with cwd=projectRoot. An empty projectRoot cannot be used as the working directory, so the guard throws this error before running the command. Note that this error is distinct from gh CLI being missing — that path returns null instead.","triggerScenarios":"Calling getGitHubRepoInfo(undefined) or '' — typically from the repoInfo wrapper when projectRoot resolution failed; also when passing an empty root straight from config.","commonSituations":"Scripts run with an unset project-root flag; monorepo tooling pointing at a root that resolved to empty string; tests that forgot to create/point to a repo fixture.","solutions":["Pass a non-empty repository path that is inside a GitHub-backed git repo","Default to process.cwd() when the configured root is missing","Verify upstream projectRoot resolution before calling; log the value if unsure","If only default-branch info is needed, handle null return paths and guard the root yourself"],"exampleFix":"// before\nconst info = await getGitHubRepoInfo(opts.projectRoot);\n// after\nconst root = opts.projectRoot || process.cwd();\nif (!root) throw new Error('Unable to determine project root');\nconst info = await getGitHubRepoInfo(root);","handlingStrategy":"validation","validationCode":"if (!projectRoot || typeof projectRoot !== 'string') {\n  throw new Error('projectRoot required before querying gh repo info');\n}\n// additionally confirm gh availability separately; missing gh returns null, not a throw:\nconst info = await getGitHubRepoInfo(projectRoot); // null when gh absent","typeGuard":"function hasRoot(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  const info = await getGitHubRepoInfo(projectRoot);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('getGitHubRepoInfo')) {\n    console.error('projectRoot missing; cannot run gh repo view.');\n    return null;\n  }\n  throw err;\n}","preventionTips":["Distinguish argument errors (throw) from tool-availability (null return) when handling","Install/authenticate gh CLI separately if repo info is required for your flow","Default the root to the repo checkout directory in CI and scripts","Assert projectRoot right after config load, before any git-utils usage"],"tags":["git","github","argument-validation"],"backgroundTag":"missing-required-parameter","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}