Skip to content

fix: AI review failed silently — octokit.issues namespace undefined#22

Merged
avrabe merged 1 commit intomainfrom
fix/ai-review-use-request-form
Apr 25, 2026
Merged

fix: AI review failed silently — octokit.issues namespace undefined#22
avrabe merged 1 commit intomainfrom
fix/ai-review-use-request-form

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Apr 25, 2026

Root cause

Every pull_request.opened event triggered an AI review that immediately failed with Cannot read properties of undefined (reading 'listComments') and (reading 'createComment'). Production logs (pm2 logs temper) confirm this hitting PRs #209, #210, … #213 in pulseengine/rivet. Zero AI review comments on any pulseengine PR since ~2026-03.

src/ai-review.js called octokit.issues.listComments, .updateComment, and .createComment. Probot v14's bundled Octokit in the pull_request.opened event context does not expose the .issues namespace plugin. The same context.octokit works through .request(route, params) — which is what every other call site in the codebase already uses.

Fix

Replace the three octokit.issues.X calls in ai-review.js with the .request() form. The test mock retrofit dispatches .request(route, params) into the existing namespaced jest.fn()s when the route matches one of those three — so all 166 ai-review test assertions still apply unchanged.

Test plan

  • All 698 tests pass
  • eslint clean
  • After merge + self-update: open any non-bot PR in any pulseengine repo. The AI review comment should appear within ~5 min.
  • If it still doesn't land, the second remaining cause is the Ollama timeout — qwen2.5-coder:3b on the netcup VPS sometimes exceeds the 300s `ai_review.timeout`. That'll be a tuning follow-up.

Risk & rollout

  • Risk: low. Pure call-shape change. Same endpoints, same params.
  • Rollout: self-update on merge.

🤖 Generated with Claude Code

…t runtime

## Root cause
On the deployed bot, every `pull_request.opened` event triggered an AI review
that immediately failed with `Cannot read properties of undefined (reading
'listComments')` and `(reading 'createComment')`. Production logs show this
hitting PRs #209, #210, … #213 in pulseengine/rivet. Zero AI review comments
have appeared on any pulseengine PR since at least 2026-03.

`src/ai-review.js` called `octokit.issues.listComments`, `.updateComment`,
and `.createComment`. Probot v14's bundled Octokit (`@octokit/rest@22`) in
the `pull_request.opened` event context does **not** expose the `.issues`
namespace plugin. The same `context.octokit` works through `.request(route,
params)` (which is what every other call site in the codebase uses).

## Fix
Replace the three `octokit.issues.X` calls with the `.request()` form:

| Was | Now |
|---|---|
| `octokit.issues.listComments({...})` | `octokit.request('GET /repos/{owner}/{repo}/issues/{issue_number}/comments', {...})` |
| `octokit.issues.updateComment({...})` | `octokit.request('PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}', {...})` |
| `octokit.issues.createComment({...})` | `octokit.request('POST /repos/{owner}/{repo}/issues/{issue_number}/comments', {...})` |

The test mock retrofit dispatches `.request(route, params)` into the existing
namespaced `jest.fn()`s when the route matches one of those three — so all
166 ai-review test assertions still apply unchanged.

## Test plan
- [x] All 698 tests pass
- [x] eslint clean
- [ ] After merge + self-update: open a draft PR in pulseengine/temper (or
      any non-bot PR in another pulseengine repo). The AI review comment
      should appear within ~5 min. If it still doesn't, the second remaining
      cause is the Ollama timeout — `qwen2.5-coder:3b` on the netcup VPS
      sometimes exceeds the 300s `ai_review.timeout`.

## Risk & rollout
- Risk: low. Pure call-shape change. Same endpoints, same params.
- Rollout: self-update on merge. Confirmation = AI review comment lands on
  the next PR opened in any pulseengine repo.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avrabe avrabe merged commit a9b8e6f into main Apr 25, 2026
5 checks passed
@avrabe avrabe deleted the fix/ai-review-use-request-form branch April 25, 2026 23:17
avrabe added a commit that referenced this pull request Apr 27, 2026
## Why
PR #29 deployed and removed the early-exit guard that silently swallowed
chatops, but at app.js:644 the very next line was:

    const workingComment = await context.octokit.issues.createComment({...});

Logs from netcup at 04:39 UTC after retriggering /review-pr on rivet#213:

    err: TypeError: Cannot read properties of undefined (reading 'createComment')
        at file:///opt/temper/src/app.js:644:59
        at issue_comment processWebhook

Same root cause as PR #22 (ai-review.js) — Probot v14's `context.octokit.issues`
is undefined for issue_comment.created webhooks too. The PR #22 fix only
covered ai-review.js; app.js had 28 more `.issues.X` call sites that all
throw the moment they're hit.

## What
- New `issueOps` helper at the top of app.js wraps the four methods that
  app.js actually uses (`createComment`, `updateComment`, `deleteComment`,
  `create`/`createIssue`) with `octokit.request(<route>, args)` calls.
- `replace_all` sweep replaced all 28 call sites:
    `context.octokit.issues.X(args)` → `issueOps.X(context.octokit, args)`
- Updated `createMockOctokit()` to dispatch `.request(route, params)` into
  the same namespaced jest.fn()s as before, so existing test assertions
  on `octokit.issues.createComment` etc. keep working unchanged.
- Three /generate-dependabot tests previously used
  `request.mockResolvedValue({...})` which clobbered the dispatcher;
  changed to `mockImplementationOnce` so dispatch survives.
- E2e webhook test: removing the guard caused the issue_comment.created
  handler to actually run; with fake test credentials it hits Probot's
  installation token fetch and returns 401. Added 401 to the accepted
  status list (alongside the existing 200/202/500).

## Test plan
- [x] All 773 tests pass (was 766; net +7 from PR #30's schema work)
- [x] eslint clean
- [ ] After deploy: `/review-pr` on rivet#213 should now post the
      "🔍 AI review in progress..." comment within seconds. Then either
      finish with a real review (oracle + model) or update with an error
      message — but no longer silently die.
- [ ] All other chatops (`/configure-repo`, `/sync-all-repos`,
      `/check-config`, etc.) keep working.

## Risk & rollout
- Risk: medium. Sweeping mechanical change across app.js. Mitigated by:
  - the 28 sites are all the same shape (object arg → object arg)
  - the `request()` form is what every other callsite in the codebase
    already uses successfully
  - 773 tests including the previously-broken e2e
- Rollout: self-update on merge.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant