{"record":{"id":"c40659bcddf3de93","repo":"eyaltoledano/claude-task-master","slug":"projectroot-is-required-for-isondefaultbranch","errorCode":null,"errorMessage":"projectRoot is required for isOnDefaultBranch","messagePattern":"projectRoot is required for isOnDefaultBranch","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/common/utils/git-utils.ts","lineNumber":265,"sourceCode":"\t\tfor (const defaultName of commonDefaults) {\n\t\t\tif (\n\t\t\t\tbranches.includes(defaultName) ||\n\t\t\t\tremoteBranches.includes(defaultName)\n\t\t\t) {\n\t\t\t\treturn defaultName;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\n/**\n * Check if we're currently on the default branch\n */\nexport async function isOnDefaultBranch(projectRoot: string): Promise<boolean> {\n\tif (!projectRoot) {\n\t\tthrow new Error('projectRoot is required for isOnDefaultBranch');\n\t}\n\n\ttry {\n\t\tconst [currentBranch, defaultBranch] = await Promise.all([\n\t\t\tgetCurrentBranch(projectRoot),\n\t\t\tgetDefaultBranch(projectRoot)\n\t\t]);\n\t\treturn (\n\t\t\tcurrentBranch !== null &&\n\t\t\tdefaultBranch !== null &&\n\t\t\tcurrentBranch === defaultBranch\n\t\t);\n\t} catch (error) {\n\t\treturn false;\n\t}\n}\n\n/**","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/common/utils/git-utils.ts#L247-L283","documentation":"isOnDefaultBranch compares the current branch with the default branch, running both lookups inside projectRoot. An empty projectRoot makes that comparison impossible, so the guard throws this error before git commands execute. It is a fail-fast argument check.","triggerScenarios":"Calling isOnDefaultBranch(undefined) or '' — typically an unset project root from config; also via Promise.all paths when the supplied root is empty string.","commonSituations":"Scripts checking 'safe to commit on main?' executed outside a configured project; pipelines where the workspace variable is empty; tests passing no fixture path.","solutions":["Pass a valid non-empty repository path to the function","Fall back to process.cwd() when the configured root is missing","Fix upstream projectRoot resolution/config loading","Wrap the call in a guard that returns false (or skips the check) when root is unknown"],"exampleFix":"// before\nconst onDefault = await isOnDefaultBranch(projectRoot); // ''\n// after\nconst onDefault = projectRoot ? await isOnDefaultBranch(projectRoot) : false;","handlingStrategy":"validation","validationCode":"if (!projectRoot || typeof projectRoot !== 'string') {\n  throw new Error('isOnDefaultBranch requires a non-empty projectRoot');\n}\n// safe pre-check of both underlying values:\nconst [cur, def] = await Promise.all([getCurrentBranch(projectRoot), getDefaultBranch(projectRoot)]);\nconst onDefault = cur !== null && def !== null && cur === def;","typeGuard":"function isRoot(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  const onDefault = await isOnDefaultBranch(projectRoot);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('isOnDefaultBranch')) {\n    console.error('projectRoot missing; skipping default-branch safety check.');\n    return false; // treat as NOT safe rather than crashing\n  }\n  throw err;\n}","preventionTips":["Treat the check as a safety gate: when root is unknown, assume not-on-default and skip risky writes","Resolve and assert projectRoot before branch-safety logic","Centralize root resolution so helpers never receive empty strings","In CI, echo the workspace path before git-dependent steps to catch empty values early"],"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"}