{"record":{"id":"32180cae9d637f41","repo":"koala73/worldmonitor","slug":"git-is-required-to-prove-the-merge-commit-reached-the","errorCode":null,"errorMessage":"git is required to prove the merge commit reached the default branch","messagePattern":"git is required to prove the merge commit reached the default branch","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/check-stacked-merge.mjs","lineNumber":300,"sourceCode":"      }\n      baseHeadPulls = listPullsByHead({ gh, repository, owner, headRef: baseRef });\n    }\n    const verdict = evaluatePreMergeGuard({ defaultBranch, baseRef, baseHeadPulls });\n    if (verdict.ok) {\n      return { ...verdict, exitCode: 0 };\n    }\n    return {\n      ...verdict,\n      exitCode: 1,\n      annotation: preMergeAnnotation(verdict, baseRef),\n    };\n  }\n\n  const mergeSha = pull.merge_commit_sha;\n  const merged = isMergedPull(pull);\n  if (!merged) return { ok: true, reason: 'not-merged', exitCode: 0 };\n  if (typeof git !== 'function') {\n    throw new Error('git is required to prove the merge commit reached the default branch');\n  }\n  const ref = `origin/${defaultBranch}`;\n  const isAncestor = merged && typeof mergeSha === 'string' && mergeSha.length > 0\n    ? confirmAncestry({\n      git,\n      commit: mergeSha,\n      ref,\n      defaultBranch,\n      shouldRetry: baseRef === defaultBranch,\n      sleep,\n    })\n    : false;\n  const { parents = [], pendingParent } = !isAncestor && mergeSha && typeof gh === 'function'\n    ? findPendingParent({ gh, git, repository, defaultBranch, pull, mergeSha })\n    : {};\n  const verdict = evaluatePostMergeAncestry({ merged, mergeSha, isAncestor, pendingParent });\n\n  const alarm = formatOrphanIssue({","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/scripts/check-stacked-merge.mjs#L282-L318","documentation":"check-stacked-merge verifies that a merged PR's merge commit is actually reachable from the remote default branch (origin/<defaultBranch>). Proving ancestry requires running git; when the injected `git` dependency is not a function (dependency not provided/wired), the script throws rather than silently skipping the ancestry proof, which would let an unmerged-to-default merge pass.","triggerScenarios":"Calling checkStackedMerge for an already-merged PR while the `git` option was omitted, passed as null/undefined, or set to a non-function (e.g. a wrong mock or a string command instead of an executor function).","commonSituations":"Test harness refactored the dependency injection and stopped passing the git executor; a caller imported the check in a new script and forgot the git option; environment without git binary combined with a lazy git wrapper that resolves to undefined.","solutions":["Pass a working git executor function to checkStackedMerge (e.g. the script's own runGit helper)","Fix the test/mock so `git` is a vi.fn/exec-style function, not undefined or a plain value","Ensure the host environment has git installed if the executor shells out to it","Confirm the option name matches the current function signature after any refactor"],"exampleFix":"// before\nawait checkStackedMerge({ pull });\n// after\nawait checkStackedMerge({ pull, git: runGit });","handlingStrategy":"validation","validationCode":"if (typeof git !== 'function') throw new Error('checkStackedMerge requires a git executor function');\nawait checkStackedMerge({ pull, git });","typeGuard":"const hasGitExecutor = (opts) => typeof opts.git === 'function';","tryCatchPattern":"try {\n  await checkStackedMerge({ pull, git });\n} catch (e) {\n  if (e.message.includes('git is required')) {\n    console.error('Wire the git executor dependency into checkStackedMerge');\n  } else throw e;\n}","preventionTips":["Always pass the git executor when calling checkStackedMerge","Update test mocks whenever the dependency-injection signature changes","Ensure git is installed where the script runs","Type-check options objects (JSDoc/TS) so a missing git option fails early"],"tags":["git","cli","internal-invariant","ci"],"backgroundTag":"missing-dependency","analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-09-15T16:44:39.439Z","contentChangedAt":"2026-09-15T16:44:39.439Z","schemaVersion":2},"datasetVersion":"2026-09-15T18:17:12.389Z"}