Skip to content

Handle deleted PR head refs non-fatally - #50051

Merged
pelikhan merged 5 commits into
mainfrom
copilot/deep-report-apply-non-fatal-handling
Aug 3, 2026
Merged

Handle deleted PR head refs non-fatally#50051
pelikhan merged 5 commits into
mainfrom
copilot/deep-report-apply-non-fatal-handling

Conversation

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

PR Sous Chef could fail an entire batch when update_pull_request encountered a deleted or force-pushed head branch. The existing stale-target handling depended on a 422 status, which is not consistently preserved through API/proxy error wrapping.

  • Safe-output error classification

    • Treat the specific head ref does not exist branch-update error as non-fatal regardless of reported HTTP status.
    • Preserve status-gated handling for other benign branch-update failures.
  • Regression coverage

    • Verify a deleted-head response reported with a non-422 status produces a non-fatal skip.
message.includes("head ref does not exist") ||
(status === 422 && isOtherBenignBranchUpdateFailure)

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 11.5 AIC · ⌖ 11.2 AIC · ⊞ 8.3K ·
Comment /souschef to run again

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Hey @Copilot 👋 — thanks for tackling this PR Sous Chef fix! I see this is marked [WIP] and currently has no code changes yet (0 lines). A few things to keep in mind:

  • Complete the implementation — This PR needs actual code changes to address the issue. The description references fixing error handling in PR Sous Chef so that "head ref does not exist" API errors are treated as non-fatal consistently across all PRs in a batch.
  • Add tests — Once the code changes are in place, make sure to include tests that verify the non-fatal handling works correctly. This is important for error-handling fixes.
  • Update PR description — The current body pulls in the full issue template. Once work begins, update it with a clear summary of changes made and how they address the problem.

The issue itself is well-defined with clear scope and a working reference implementation already in the codebase. Once you have changes to show, the PR should be ready for review.

Review the PR Sous Chef workflow's `update_pull_request` error handling to identify where "head ref does not exist" API errors are currently hard-failing. Find the existing non-fatal code path mentioned in issue #50019 and apply that handling uniformly to all PRs processed in the run. Add unit tests verifying the non-fatal behavior for this specific error condition.

Generated by ✅ Contribution Check · auto · 48.7 AIC · ⌖ 5.57 AIC · ⊞ 8.8K ·

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Apply PR Sous Chef non-fatal handling for head ref errors Handle deleted PR head refs non-fatally Aug 3, 2026
Copilot AI requested a review from pelikhan August 3, 2026 17:41
@pelikhan
pelikhan marked this pull request as ready for review August 3, 2026 18:09
Copilot AI review requested due to automatic review settings August 3, 2026 18:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #50019 by treating deleted PR head references as non-fatal during branch updates.

Changes:

  • Classifies “head ref does not exist” independently of HTTP status.
  • Adds regression coverage for a non-422 response.
Show a summary per file
File Description
actions/setup/js/update_pull_request.cjs Updates non-fatal error classification.
actions/setup/js/update_pull_request.test.cjs Verifies non-fatal handling with status 404.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Balanced

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

PR Triage: #50051

  • Category: bug
  • Risk: low
  • Score: 58/100 (Impact 25 + Urgency 15 + Quality 18)
  • Recommended action: auto_merge

Small, focused fix (11+/8-) with all 12 CI checks passing. Prevents PR Sous Chef from failing entire batches on deleted head refs. Candidate for auto-merge.

Generated by 🔧 PR Triage Agent · auto · 51.1 AIC · ⌖ 4.08 AIC · ⊞ 8K ·

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR does not have the implementation label and has 0 new lines of code in business logic directories.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: Request changes — the status guard was removed too broadly for the head ref does not exist match.

💡 Themes
  • The fix correctly addresses the reported bug (stale head ref reported with unexpected status), but the implementation matches the message substring with no status constraint at all, rather than a bounded set like 404 | 422 | undefined. This risks silently swallowing genuinely fatal errors (e.g. 500s, network/proxy errors) that happen to contain this substring.
  • Test coverage only adds a 404 case; there's no test guarding against unrelated/unexpected statuses being misclassified as non-fatal.
  • Everything else in the diff (comment updates, other status-gated conditions) looks accurate and consistent with the stated intent.

🔎 Code quality review by PR Code Quality Reviewer · auto · 14.5 AIC · ⌖ 4.57 AIC · ⊞ 7.9K
Comment /review to run again

Comments that could not be inline-anchored

actions/setup/js/update_pull_request.cjs:29

Matching head ref does not exist unconditionally on status (not just 404/422) means any non-fatal-status branch-update failure (500, 401, network-wrapped errors, etc.) whose message happens to contain this substring is now silently swallowed as non-fatal.

<details><summary>💡 Details</summary>

Before this change, the early-return guarded on status !== 422 (with 403 handled separately), so only 422/undefined/403 statuses could reach the final return. Now the guard is `status !== 422 && !me…

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs — one actionable finding on the error-classification logic.

📋 Key Themes & Highlights

Key Themes

  • Status-undefined gap: The new message.includes("head ref does not exist") guard in the return expression is not restricted to errors with a known HTTP status. A network/proxy error with no status (i.e. status === undefined) that contains this substring in its message would be treated as non-fatal, which may not be intended.

Positive Highlights

  • ✅ Clean, minimal change — only the necessary lines are modified
  • ✅ Test case is correctly flipped from fatal → non-fatal with the right expectation added
  • ✅ Updated comments accurately reflect the new intent
  • ✅ The early-return guard at line 55 correctly threads the head ref does not exist case through to the final return, avoiding double-evaluation

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 28.8 AIC · ⌖ 12.1 AIC · ⊞ 7.1K
Comment /matt to run again

// the if-block above.
return (
(status === 422 && (message.includes("there are no new commits on the base branch") || message.includes("merge conflict between base and head") || message.includes("head ref does not exist"))) ||
message.includes("head ref does not exist") ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] The message.includes("head ref does not exist") check here is not gated by any status — it matches even when status === undefined (network/proxy errors with no HTTP status), not just when the API returns a non-422 status. The PR description intends to handle the status-mismatch case, not the no-status case.

💡 Suggested guard

Consider:

return (
  (status !== undefined && message.includes("head ref does not exist")) ||
  (status === 422 && (message.includes("there are no new commits on the base branch") || message.includes("merge conflict between base and head"))) ||
  ((hasWorkflowsPermissionError || hasWorkflowsScopeRequired) && status === undefined)
);

This keeps the status === undefined arm exclusive to workflows-permission errors as originally designed.

@copilot please address this.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change is correct and well-targeted. Extracting "head ref does not exist" from the status === 422 gate means deleted/force-pushed head branches are treated as non-fatal regardless of how an API proxy wraps the HTTP status. The accompanying test is updated to assert the new non-fatal path. No security, correctness, or reliability concerns.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 18.1 AIC · ⌖ 9.18 AIC · ⊞ 5.4K

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: N/A — Minimal Test Modification

Analyzed 1 modified test in JavaScript (no new tests added). Test expectations updated to verify new non-fatal behavior for deleted PR head refs.

📊 Metrics (1 test)
Metric Value
Analyzed 1 (JS: 1)
✅ Design 1 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 1 (100%)
Duplicate clusters 0
Inflation No (0.375:1 ratio)
🚨 Violations 0
🧪 Test Analysis

Modified Test: should treat head-ref-missing as non-fatal regardless of updateBranch status

  • File: actions/setup/js/update_pull_request.test.cjs:963
  • Classification: Design test, behavioral contract
  • Change: Test expectation updated from result.success === false (was testing fatal behavior) to result.success === true (now tests non-fatal behavior)
  • Scope: Tests the new guarantee that deleted PR head refs are handled non-fatally regardless of HTTP status code (previously only 422 was treated as non-fatal; now ANY status with the "head ref does not exist" message is non-fatal)
  • Assertions (4 total):
    • result.success === true (verifies non-fatal behavior)
    • ✅ updateBranch called once (confirms attempted operation)
    • ✅ update not called (confirms branch operation didn't proceed to title/body update)
    • ✅ warning message issued with "branch from base (non-fatal)" (verifies warning logged)
  • Edge case: Tests with 404 status (whereas companion test at line 927 uses 422) — good coverage of status-code variation

Context of Related Tests:

  • Line 927: Same error message + status 422 → non-fatal (existing, unchanged)
  • Line 941: Same error message + status 422 + title update → non-fatal + continues updates (existing, unchanged)
  • Line 963: Same error message + status 404 → non-fatal (modified; now matches production logic)

Quality Signals:

  • ✅ Behavioral contract enforced: deleted PR head refs are non-fatal regardless of status
  • ✅ Edge cases covered: multiple HTTP status codes (422, 404)
  • ✅ Integration: confirms warning messaging
  • ✅ Design invariant: test title and expectations now match actual behavior

Verdict

passed. One existing test was correctly updated to reflect the new design invariant (deleted PR head refs are non-fatal). No implementation-only tests added. Test code inflation is minimal (3 lines vs 8 production lines). Test remains focused on observable behavior and design contract. No violations.

Quality Signal: This change demonstrates good testing discipline — modifying test expectations to match intentional behavior changes, rather than adding redundant new tests. The existing test suite provides 3 complementary scenarios covering different status codes and continuation behavior.

🧪 Test quality analysis by Test Quality Sentinel · haiku45 · 23.1 AIC · ⌖ 6.04 AIC · ⊞ 8.5K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: Minimal Modification — Passed.

1 JavaScript test was correctly updated to reflect the new design invariant: deleted PR head refs are treated as non-fatal regardless of HTTP status code (previously only 422 was non-fatal).

Metrics:

  • Modified tests: 1 (design-focused)
  • Implementation-only tests: 0
  • Edge-case coverage: Good (422 and 404 status codes tested)
  • Test inflation: No (0.375:1 ratio)
  • Violations: None

The test now correctly verifies that the behavior is non-fatal for any HTTP status when "head ref does not exist" is detected, complementing the existing 422-status tests.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot sous-chef triage:

Unresolved review threads remain:

Please address the unresolved review feedback, refresh the branch if needed, then run the pr-finisher skill and post a concise merge-readiness summary for the current head.

Generated by PR Sous Chef · run: https://github.com/github/gh-aw/actions/runs/30848087243

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 11.5 AIC · ⌖ 11.2 AIC · ⊞ 8.3K ·
Comment /souschef to run again

Copilot AI and others added 2 commits August 3, 2026 20:13
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
@pelikhan

pelikhan commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

@copilot keep working

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot keep working

Current head is 5bd0eef. Local validation passed (make agent-report-progress), the previously unresolved inline review is now outdated after the fix, and the visible PR check runs for this head are green apart from the in-progress Copilot run. Ready for human merge once maintainers are satisfied with review state and CI on this head.

@copilot sous-chef triage:

Unresolved review threads remain:...

Addressed in 5bd0eef. The deleted-head non-fatal path now requires a numeric status, and /home/runner/work/gh-aw/gh-aw/actions/setup/js/update_pull_request.test.cjs covers the statusless case as fatal.

@pelikhan
pelikhan merged commit a48435c into main Aug 3, 2026
9 checks passed
@pelikhan
pelikhan deleted the copilot/deep-report-apply-non-fatal-handling branch August 3, 2026 20:48
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.84.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[deep-report] Apply PR Sous Chef non-fatal handling for "head ref does not exist" uniformly

4 participants