From adb5a843db8744c76512c7ad21eed568dcb0a4b1 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Fri, 1 May 2026 18:15:28 +0200 Subject: [PATCH] fix: sweep last context.octokit.repos.getBranch in app.js to .request() form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Why Wave-1 Probot/Octokit expert flagged this as Bug #16 in `docs/agent-fleet/bugs.md`: `src/app.js:268` was the one remaining `context.octokit.repos.getBranch(...)` call after PR #22 / #29 / #30 swept `.issues.X` to `.request()`. Same root cause — Probot v14 sometimes ships `context.octokit` without the namespaced REST plugin, so the `.repos` namespace is undefined at runtime and the call throws synchronously inside the `repository.created` handler retry loop. Note: `dashboard.js` also uses namespaced calls (`octokit.repos.X`, `octokit.pulls.list`, etc.) but it builds its OWN `@octokit/rest@22` client (`dashboard.js:31-36`) where the namespaces are reliably loaded; those calls are intentionally left as-is. ## What Replace the lone `context.octokit.repos.getBranch({owner, repo, branch})` with `octokit.request('GET /repos/{owner}/{repo}/branches/{branch}', {...})`. Identical behaviour, idiomatic v14, immune to the namespace issue. Test mock retrofit: `createMockOctokit` in `__tests__/integration/app.test.js` now also dispatches `GET /repos/{owner}/{repo}/branches/{branch}` into the existing `repos.getBranch` jest.fn() so tests asserting on `context.octokit.repos.getBranch.mockRejectedValue(...)` still work. ## Test plan - [x] 834 tests pass — including the existing `repository.created` tests that assert the 404-retry loop and the `skipBranchScopedWork` path - [x] eslint clean ## Risk & rollout - Risk: low. Pure call-shape change. Same endpoint, same params. - Rollout: self-update on merge. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) --- __tests__/integration/app.test.js | 11 +++++++++-- src/app.js | 12 +++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/__tests__/integration/app.test.js b/__tests__/integration/app.test.js index da1cb5a..12e72ec 100644 --- a/__tests__/integration/app.test.js +++ b/__tests__/integration/app.test.js @@ -148,11 +148,18 @@ function createMockOctokit() { const issuesUpdateComment = jest.fn().mockResolvedValue({}); const issuesDeleteComment = jest.fn().mockResolvedValue({}); + // Production now uses `.request()` for `repos.getBranch` too (PR fixing + // Bug #16 — `app.js:268` was on `context.octokit.repos.getBranch` which + // shares the PR-#22 failure mode). Route GET branches into a namespaced + // mock so existing `octokit.repos.getBranch.mockX` test calls still work. + const reposGetBranch = jest.fn().mockResolvedValue({ data: { name: 'main' } }); + const routeDispatch = { 'POST /repos/{owner}/{repo}/issues': issuesCreate, 'POST /repos/{owner}/{repo}/issues/{issue_number}/comments': issuesCreateComment, 'PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}': issuesUpdateComment, - 'DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}': issuesDeleteComment + 'DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}': issuesDeleteComment, + 'GET /repos/{owner}/{repo}/branches/{branch}': reposGetBranch }; const request = jest.fn((route, params) => { @@ -169,7 +176,7 @@ function createMockOctokit() { deleteComment: issuesDeleteComment }, repos: { - getBranch: jest.fn().mockResolvedValue({ data: { name: 'main' } }) + getBranch: reposGetBranch }, request }; diff --git a/src/app.js b/src/app.js index db1446d..e55546f 100644 --- a/src/app.js +++ b/src/app.js @@ -265,11 +265,13 @@ function registerApp(app, options = {}) { for (let attempt = 1; attempt <= 3; attempt++) { try { - await context.octokit.repos.getBranch({ - owner, - repo: repoName, - branch: defaultBranch - }); + // Use .request() form rather than .repos.getBranch — Probot v14's + // `context.octokit.repos` namespace is unreliable on this event + // type (same root cause as PRs #22 / #29 / #30 for `.issues.X`). + await context.octokit.request( + 'GET /repos/{owner}/{repo}/branches/{branch}', + { owner, repo: repoName, branch: defaultBranch } + ); branchReady = true; break; } catch (err) {