Skip to content

PR Review Agent — failures detected 2026-05-06 #33

Description

@github-actions

1. Executive Summary

Over the last 24 hours the PR Review Agent completed 22 runs: 19 succeeded and 3 failed (13.6% failure rate). The single fully-logged failure (run #599) reveals two compounding errors during the post-review branch-update step for petry-projects/markets/pull/99: a GitHub GraphQL API 504 Gateway Timeout followed immediately by a 403 "user doesn't have permission to update head repository". Together these cause review-one-pr.sh to exit non-zero, which the batch loop treats as session-fatal, aborting the entire run. The 403 is a structural permission gap — the bot PAT (DON_PETRY_BOT_PETRY_PROJECT_PAT) cannot push to PR head branches it doesn't own. Logs for runs #595 and #596 are unavailable, but their timing (two consecutive failures at 13:45 and 14:52, followed by a clean run at 15:46) is consistent with the same transient-plus-permission pattern. Urgency: DEGRADED — the pipeline recovers and retries, but any PR requiring a rebase will reliably abort the batch session.


2. Failure Breakdown

Failure Category Affected Runs Example Error Message
Permission / auth error (403) #599 (confirmed), #595/#596 (probable) {"message":"user doesn't have permission to update head repository","status":"403"}
Timeout / infrastructure (504) #599 (confirmed) HTTP 504: 504 Gateway Timeout (https://api.github.com/graphql)
Review dismiss failure (422) #599 (warning, non-fatal) gh: Validation Failed (HTTP 422) — failed to dismiss prior agent review 4125073439
Unknown / log unavailable #595, #596 (logs not retrieved for runs 25380169511 and 25383796920)

3. Error Patterns

Pattern A — 403 on branch update ("update head repository")

Exact error:

{"message":"user doesn't have permission to update head repository",
 "documentation_url":"https://docs.github.com/rest/pulls/pulls#update-a-pull-request-branch",
 "status":"403"}

Step / script: Review each PR (cascade)scripts/review-one-pr.sh, in the "Branch is BEHIND, requesting rebase…" code path (REST PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch).

Root cause: The donpetry-bot PAT does not have write access to the source/head repository of the PR. For PRs opened from branches inside petry-projects/* repos where the bot is not a collaborator with push rights — or for any fork-based PR — GitHub's API rejects branch-update requests with 403. The review itself succeeded (APPROVED was posted); only the rebase request failed. However review-one-pr.sh propagates this non-zero exit to the batch loop, which classifies it as session-fatal and aborts all remaining candidates.


Pattern B — 504 Gateway Timeout on GraphQL

Exact error:

HTTP 504: 504 Gateway Timeout (https://api.github.com/graphql)

Step / script: Same step as Pattern A — the review-one-pr.sh rebase path, just before the 403. The 504 is from a GraphQL call (likely checking branch status or issuing the update mutation) and reflects transient GitHub API instability at that moment (17:44 UTC on May 5). It does not cause the abort by itself, but it precedes and likely compounds the 403 handling.


Pattern C — 422 on prior review dismissal (non-fatal warning)

Exact error:

cleanup: failed to dismiss prior agent review 4125073439 on
https://github.com/petry-projects/markets/pull/99 —
duplicates will stack until resolved. API said: gh: Validation Failed (HTTP 422)

Step / script: review-one-pr.sh, in the pre-post cleanup that dismisses the previous bot review before submitting a new one.

Root cause: The review 4125073439 is in a state that cannot be dismissed via the API — most likely it was already dismissed, submitted as a non-pending review, or the PR was merged/closed between enumeration and review. The script correctly emits a ::warning:: and continues, so this does not cause the failure, but stale duplicate reviews will accumulate on the PR.


4. Token Scope Analysis

Scopes currently confirmed present (from gh auth status in run #599):

Token Account Protocol Notes
DON_PETRY_BOT_PETRY_PROJECT_PAT (github_pat_11CDFSYKQ0…) donpetry-bot HTTPS Active, authenticated

The workflow's permissions: block grants:

  • contents: read
  • pull-requests: write
  • checks: read

These are the workflow-token permissions; the actual API calls use the PAT, which operates under its own OAuth scopes.

Scopes that appear missing or insufficient:

Scope / Permission Evidence of Gap Recommendation
Write access to petry-projects/* head branches 403 on PUT .../update-branch for markets/pull/99 Add donpetry-bot as a collaborator with Write or Maintain role on each repo in petry-projects org, OR grant it org-level member write rights; alternatively, give petry-projects org owner the bot with a role that allows branch updates
GraphQL API stability 504 on api.github.com/graphql Not a scope issue — transient infrastructure; retry logic in the script would mitigate
Pull request review dismiss 422 on dismiss of review 4125073439 Possibly a timing/state issue rather than a scope gap; verify the review state before attempting dismissal

5. Recommendations

  1. [CRITICAL] Make the rebase/branch-update step non-fatal in review-one-pr.sh

    The 403 on branch update should be a warning, not a session-abort. The review was already posted successfully; failing to request a rebase is cosmetic. Change the branch-update call to use || true or an explicit rc check that treats the 403/non-zero exit as a ::warning:: and continues. The current code propagates the error as exit code 1, which the batch loop treats as session-fatal and halts all remaining PRs.

    • File: scripts/review-one-pr.sh — branch-update / rebase-request section
    • Why: A permanent permission gap (bot cannot push to head repos it doesn't own) is causing every batch that encounters a behind-branch PR to abort early
    • Expected impact: Eliminates the session-abort failure mode; the rebase warning will be visible in logs but the queue will complete
    • Urgency: CRITICAL
  2. [HIGH] Grant donpetry-bot write access to petry-projects repos (or use a token that has it)

    If requesting rebases is a desired feature (not just cosmetic), the bot's PAT must have push access to the head branch. Either:

    • Add donpetry-bot as a collaborator with Write role in each petry-projects repo, or

    • Create a scoped installation token (GitHub App) with contents: write on petry-projects — this is more secure than a broad PAT

    • File: GitHub repo/org settings + secrets management

    • Why: Without write access the 403 is permanent; every PR that falls behind main will fail to get the auto-rebase

    • Expected impact: Restores auto-rebase functionality; removes the root cause of the 403

    • Urgency: HIGH

  3. [HIGH] Retrieve and inspect logs for runs 💡 Per-Tier MCP Tool Gating with Selective LSP Tool Exposure #595 and 💡 Token Cost Observatory LSP Metrics: Measuring the ROI of Semantic Code Intelligence #596

    Two consecutive failures around 13:45–14:52 UTC on May 5 have no available logs. Without them, the diagnosis is incomplete. Retrieve them via gh run view 25380169511 --log and gh run view 25383796920 --log to confirm whether they share the same 403/504 root cause or represent a separate issue.

    • File: Health-check / monitoring script
    • Why: The pattern (two failures, then recovery) could indicate a different transient error (rate limit, infra blip) that may recur
    • Urgency: HIGH
  4. [MEDIUM] Add retry logic around the GraphQL/branch-update call

    The 504 Gateway Timeout is transient but precedes the 403 in the failure chain. A short exponential-backoff retry (2–3 attempts) around the branch-update REST call would absorb GitHub API blips without propagating them as failures.

    • File: scripts/review-one-pr.sh — branch-update section
    • Why: Transient 504s from api.github.com/graphql are expected occasionally; retrying is safer than failing
    • Expected impact: Reduces transient-infrastructure failures; does not fix the 403
    • Urgency: MEDIUM
  5. [MEDIUM] Guard review dismissal against already-dismissed or terminal-state reviews

    Before calling gh pr review dismiss, check the current state of the review. If it is already dismissed, in a merged PR, or in a non-dismissable state, skip the dismiss call silently rather than emitting a ::warning:: about stacking duplicates.

    • File: scripts/review-one-pr.sh — pre-post cleanup section
    • Why: The 422 will recur on any PR that gets reviewed twice in short succession or where the prior review state has changed; the warning is noisy and the stacked duplicates will confuse PR authors
    • Urgency: MEDIUM
  6. [LOW] Surface log-retrieval failures in the health report

    Runs 💡 Per-Tier MCP Tool Gating with Selective LSP Tool Exposure #595 and 💡 Token Cost Observatory LSP Metrics: Measuring the ROI of Semantic Code Intelligence #596 show (log unavailable) in the report. The health-check script should distinguish between "run failed and log was fetched" vs "run failed and log could not be retrieved," and should alert (e.g., via ::warning::) when failure logs are missing so the operator knows the diagnosis is incomplete.

    • File: Health-check / log-fetch script
    • Urgency: LOW

6. Health Score

Health: 7/10 — Pipeline is mostly functional but a structural 403 permission gap causes every batch that encounters a behind-branch PR to abort early, and two additional failures remain undiagnosed due to missing logs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    automated-reportCreated by automated workflowhealth-checkAutomated health check report

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions