Skip to content

fix: fast-fail copilot harness when LLM invocation cap is saturated#45827

Merged
pelikhan merged 30 commits into
mainfrom
copilot/fix-fast-fail-on-retry
Jul 16, 2026
Merged

fix: fast-fail copilot harness when LLM invocation cap is saturated#45827
pelikhan merged 30 commits into
mainfrom
copilot/fix-fast-fail-on-retry

Conversation

Copilot AI commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

When a run exhausts the per-run LLM invocation cap (CAPIError: 429 Maximum LLM invocations exceeded (N/N)), the pooled budget is shared across all retry attempts in the Execute step. Every --continue retry therefore re-fails instantly with 0B output — the retries are provably useless but the harness kept looping until manually cancelled.

Root cause

harness_retry_guard.cjs already detected maxRunsExceeded via MAX_RUNS_EXCEEDED_PATTERNS, but copilot_harness.cjs never checked that field — only aiCreditsExceeded and awfAPIProxyBlockingRequests were wired into the guard check.

Changes

copilot_harness.cjs

  • Moved nonRetryableGuard computation before classifyCopilotFailure so isInvocationCapExceeded = nonRetryableGuard.maxRunsExceeded is available for classification and the failure log line
  • Added isInvocationCapExceeded to the guard-check block — breaks out of the retry loop immediately with a clear message indicating which attempt's partial output is preserved
  • Added isInvocationCapExceeded to the diagnostic log fields

classifyCopilotFailure

  • New isInvocationCapExceeded input → returns "invocation_cap_exceeded" (takes precedence over capi_quota_exceeded)

detect_agent_errors.cjs

  • New INVOCATION_CAP_EXCEEDED_PATTERN matches both the CAPI form (CAPIError: 429 Maximum LLM invocations exceeded (N/N)) and the Anthropic JSON form ("type":"max_runs_exceeded")
  • Wired into detectErrors() and writeOutputs() as a new invocation_cap_exceeded GitHub Actions output variable

Tests

  • 13 new test cases: pattern matching for both error forms, retry-policy fast-fail, classifyCopilotFailure classification and precedence over capi_quota_exceeded, and detectErrors() output integrity

Before: attempt 1 exhausts 25/25 invocations → attempts 2–4 each hit 429 (25/25) with 0B output → job stalls until manually cancelled
After: attempt 1 exhausts 25/25 → guard fires → harness logs "LLM invocation cap saturated — pooled per-run budget fully exhausted; retries cannot make progress (attempt 1 partial output preserved as run result)" → exits immediately

Copilot AI and others added 2 commits July 15, 2026 22:00
When a run hits the per-run LLM invocation cap
(`CAPIError: 429 Maximum LLM invocations exceeded (N/N)`) the pooled
budget is already saturated — subsequent `--continue` retries instantly
re-fail with 0B of new output and cannot make progress.

Changes:
- copilot_harness.cjs: move `nonRetryableGuard` computation before
  `classifyCopilotFailure` so `isInvocationCapExceeded` is available for
  classification and the failure log; wire `nonRetryableGuard.maxRunsExceeded`
  into the guard-check block so the harness breaks out of the retry loop
  with a clear message instead of continuing to exhausted retries.
- classifyCopilotFailure: add `isInvocationCapExceeded` → returns
  `"invocation_cap_exceeded"` (outranks `capi_quota_exceeded`).
- detect_agent_errors.cjs: add `INVOCATION_CAP_EXCEEDED_PATTERN` that
  matches both the CAPI form and the Anthropic JSON `max_runs_exceeded`
  form; wire it into `detectErrors()` and `writeOutputs()` as a new
  `invocation_cap_exceeded` GitHub Actions output variable; update the
  file-level JSDoc.
- Tests: add 13 new test cases covering pattern matching, retry-policy
  fast-fail for both CAPI and Anthropic forms, `classifyCopilotFailure`
  classification and precedence, and `detectErrors()` output.

Closes #44788

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…ssage and clarify test name

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix fast-fail for saturated invocation budget in Copilot harness fix: fast-fail copilot harness when LLM invocation cap is saturated Jul 15, 2026
Copilot AI requested a review from pelikhan July 15, 2026 22:03
@pelikhan pelikhan marked this pull request as ready for review July 15, 2026 22:07
Copilot AI review requested due to automatic review settings July 15, 2026 22:07

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

Fast-fails Copilot retries when the shared LLM invocation cap is exhausted.

Changes:

  • Adds invocation-cap detection and classification.
  • Stops retries immediately and improves diagnostics.
  • Adds pattern and retry-policy tests.
Show a summary per file
File Description
actions/setup/js/copilot_harness.cjs Adds fast-fail guard and classification.
actions/setup/js/copilot_harness.test.cjs Adds retry and classification tests.
actions/setup/js/detect_agent_errors.cjs Detects and emits invocation-cap errors.
actions/setup/js/detect_agent_errors.test.cjs Tests supported error forms and detection results.

Review details

Tip

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

  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Medium

`model_not_supported_error=${results.modelNotSupportedError}`,
`http_400_response_error=${results.http400ResponseError}`,
`capi_quota_exceeded_error=${results.capiQuotaExceededError}`,
`invocation_cap_exceeded=${results.invocationCapExceeded}`,
Comment thread actions/setup/js/copilot_harness.cjs Outdated
if (nonRetryableGuard.aiCreditsExceeded) reasons.push("AI credits budget exceeded");
if (nonRetryableGuard.awfAPIProxyBlockingRequests) reasons.push("AWF API proxy is blocking requests");
if (isInvocationCapExceeded) {
const budgetMsg = result.hasOutput ? `attempt ${attempt + 1} partial output preserved as run result` : "no output produced";
if (result.exitCode === 0) return false;
if (hasNumerousPermissionDeniedIssues(result.output)) return false;
if (isCAPIQuotaExceededError(result.output)) return false;
if (detectNonRetryableHarnessGuard(result.output).maxRunsExceeded) return false;
@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk low
Score 65 / 100
Action fast_track
Batch js-runtime-fixes (with #45826, #45825)

Score breakdown: Impact 30 + Urgency 22 + Quality 13

Adds fast-fail when LLM invocation cap is hit (429 CAPI), preventing useless retries that waste runner time. JS-layer change with tests. CI passing (17/17). Part of JS runtime fixes batch.

Run §29462479491

Generated by 🔧 PR Triage Agent · 189.6 AIC · ⌖ 5.52 AIC · ⊞ 5.6K ·

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

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

No ADR enforcement needed: PR #45827 does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold: 100).

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions github-actions Bot mentioned this pull request Jul 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

⚠️ Test Quality Score: 75/100 — Acceptable

Analyzed 10 test(s): 10 design, 0 implementation, 0 violation(s).

📊 Metrics (10 tests)
Metric Value
Analyzed 10 (Go: 0, JS: 10)
✅ Design 10 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 10 (100%)
Duplicate clusters 1
Inflation YES — both test files exceed 2:1 ratio
🚨 Violations 0
Test File Classification Issues
INVOCATION_CAP_EXCEEDED_PATTERN — CAPI 429 form detect_agent_errors.test.cjs design_test / high_value
INVOCATION_CAP_EXCEEDED_PATTERN — embedded in log detect_agent_errors.test.cjs design_test / high_value
isInvocationCapExceededError — Anthropic JSON form detect_agent_errors.test.cjs design_test / high_value
isInvocationCapExceededError — human-readable form detect_agent_errors.test.cjs design_test / high_value
isInvocationCapExceededError — case-insensitive detect_agent_errors.test.cjs design_test / high_value
isInvocationCapExceededError — does not match unrelated detect_agent_errors.test.cjs design_test / high_value
does not retry — CAPI form (cap saturated) copilot_harness.test.cjs design_test / high_value
does not retry — Anthropic JSON form (cap saturated) copilot_harness.test.cjs design_test / high_value minor dup pattern with detect_agent_errors
classifies as invocation_cap_exceeded copilot_harness.test.cjs design_test / high_value
invocation_cap_exceeded outranks capi_quota_exceeded copilot_harness.test.cjs design_test / high_value
⚠️ Flagged Tests (2) — inflation only, no action required

copilot_harness.test.cjs — +35 test lines vs +11 prod lines (ratio 3.2:1). Acceptable: the new production code is a compact fast-fail guard; tests must cover multiple error-message variants. No blocking issue.

detect_agent_errors.test.cjs — +76 test lines vs +34 prod lines (ratio 2.2:1). Marginally above the 2:1 threshold. Multiple positive/negative regex variants across 5 sub-tests for INVOCATION_CAP_EXCEEDED_PATTERN justify the volume.

Verdict

Passed. 0% implementation tests (threshold: 30%). Score penalty from test inflation (both files >2:1), but all new tests are high-value behavioral contracts verifying fast-fail LLM invocation-cap logic end-to-end: pattern matching, isInvocationCapExceededError helper, retry suppression, and failure classification priority.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 44.3 AIC · ⌖ 10.4 AIC · ⊞ 6.8K ·
Comment /review to run again

@pelikhan

Copy link
Copy Markdown
Collaborator

Copilot AI and others added 3 commits July 16, 2026 08:01
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@copilot merge main and recompile
Fix https://github.com/github/gh-aw/actions/runs/29480441627/job/87562713176

Merged main (already up to date), recompiled, and fixed the failing CGO test job in 11701d8.

@pelikhan

Copy link
Copy Markdown
Collaborator

Copilot AI and others added 2 commits July 16, 2026 08:31
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@copilot fix https://github.com/github/gh-aw/actions/runs/29482801860/job/87570627774?pr=45827

Fixed in 1084d63. I investigated the failing CGO job logs and updated the stale test expectations to match the current embedded action/container pins (gh-aw-mcpg:v0.4.1, actions/setup-node@v7, and a known existing container in spec tests). Targeted package tests now pass for the failing cases.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review comments, fix any failing checks, and rerun checks once the branch is up to date.

Generated by 👨‍🍳 PR Sous Chef · 8.77 AIC · ⌖ 6.55 AIC · ⊞ 5.1K ·
Comment /souschef to run again

…-on-retry

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address unresolved review comments, fix any failing checks, and rerun checks once the branch is up to date.

...

Completed a pr-finisher pass on this branch.

  • Merged main into this PR in b57d59fcbd (branch is now up to date with base).
  • Re-checked unresolved review feedback: the remaining points are already covered by existing changes in this branch (no additional code edits were needed in this pass).
  • Investigated current checks via Actions API: no failed jobs in the latest PR run snapshot (run_id=29484652912, failed_jobs=0).
  • Re-ran local validation successfully after the merge: make fmt, make lint, make test-unit, make test, make recompile.

I can’t trigger fresh CI from this cloud-agent path; a maintainer re-trigger is still required (close/reopen PR, workflow_dispatch, or maintainer push).

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot merge main recompile fix conflicts

Copilot AI and others added 2 commits July 16, 2026 10:12
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@copilot merge main recompile fix conflicts

Merged main, resolved conflicts, and recompiled in 0524f1c.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill on this PR. Address the unresolved review feedback and then rerun checks.

Unresolved review threads (newest first):

Please reply in-thread where appropriate and resolve the addressed threads once the fixes land.

Generated by 👨‍🍳 PR Sous Chef · 9.88 AIC · ⌖ 6.21 AIC · ⊞ 7.5K ·
Comment /souschef to run again

@pelikhan pelikhan merged commit b782292 into main Jul 16, 2026
37 of 38 checks passed
@pelikhan pelikhan deleted the copilot/fix-fast-fail-on-retry branch July 16, 2026 10:45
Copilot stopped work on behalf of gh-aw-bot due to an error July 16, 2026 10:45
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.

Copilot harness retries max-turns/invocation-cap exhaustion against a saturated pooled budget (guaranteed instant re-fail; should fast-fail)

4 participants