Skip to content

Improve Copilot organization billing failure guidance - #60877

Merged
pelikhan merged 2 commits into
mainfrom
copilot/handle-special-errors
Sep 14, 2026
Merged

pelikhan merged 2 commits into
mainfrom
copilot/handle-special-errors

Conversation

Copilot AI commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Copilot workflows using copilot-requests: write can receive authorization errors when organization billing is unavailable. Existing failure comments incorrectly suggest checking provider credentials.

  • Detection

    • Recognize the three reported Copilot authorization signatures.
    • Confirm organization-billed authentication from the agent log to avoid misclassifying PAT failures.
  • Remediation

    • Explain where organization owners can enable Copilot CLI billing.
    • Offer COPILOT_GITHUB_TOKEN with copilot-requests: none as the fallback.
    • Suppress conflicting generic credential guidance.
  • Coverage

    • Add focused tests for detection, PAT isolation, and rendered guidance.
    • Add a patch changeset.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI requested a review from pelikhan September 14, 2026 15:54
@pelikhan
pelikhan marked this pull request as ready for review September 14, 2026 16:07
Copilot AI balanced review requested due to automatic review settings September 14, 2026 16:07
@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

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

Warning

Firewall blocked 1 domain

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

  • registry.npmjs.org

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

network:
  allowed:
    - defaults
    - "registry.npmjs.org"

See Network Configuration for more information.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Lean already. Ship.

Warning

Firewall blocked 1 domain

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

  • ab.chatgpt.com

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

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by Ponytail Reviewer for #60877

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Security scanning failed for Design Decision Gate 🏗️. Review the logs for details.

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

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ PR Code Quality Reviewer failed during code quality review.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

🔎 Code quality review by PR Code Quality Reviewer

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.

🟡 Changes recommended

Proxy host variants are missed, and billing failures remain categorized as generic agent failures.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds targeted Copilot organization-billing failure detection and remediation.

Changes:

  • Detects organization-billed Copilot authorization failures.
  • Adds billing/PAT guidance while suppressing conflicting advice.
  • Adds focused tests and a patch changeset.
File summaries
File Description
.changeset/patch-copilot-org-billing-agent-failure.md Records the patch.
actions/setup/md/copilot_org_billing_error.md Defines remediation guidance.
actions/setup/md/agent_failure_comment.md Includes the new comment context.
actions/setup/md/agent_failure_issue.md Includes the new issue context.
actions/setup/js/handle_agent_failure.cjs Implements detection and rendering.
actions/setup/js/handle_agent_failure.test.cjs Tests detection and guidance.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 2
  • Review effort level: Balanced

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

const ENGINE_MAX_RUNS_EXCEEDED_RE = /(?:\bmax_runs_exceeded\b|\bmaximum\s+llm\s+invocations\s+exceeded\b)/i;
const COPILOT_ORG_BILLING_MODE_RE = /API proxy enabled:[^\n]*Copilot=true \(github-token\)/i;
const COPILOT_ORG_BILLING_ERROR_RE =
/(?:awf-reflect: models fetch returned 403\b|Copilot requests authentication failed through the gh-aw API proxy \(HTTP 403\b|Authentication failed with provider at (?:https?:\/\/)?(?:api-proxy|(?:172\.(?:1[6-9]|2\d|3[01])|10|192\.168)\.\d+\.\d+)(?::\d+)?[^\n]*\(HTTP 403\)|Access denied by policy settings|invalid access to inference)/i;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Aligned in 8dc6865: the provider-auth host alternation now mirrors isLikelyAWFAPIProxyURL (api-proxy, host.docker.internal, localhost, 127.*, 10.*, 192.168.*, 172.16-31.*), so host-bridge 403s are classified as billing failures. Added coverage for each host variant.

const timeoutMinutes = process.env.GH_AW_TIMEOUT_MINUTES || "";
const { aiCredits, maxAICredits, aiCreditsRateLimitError, maxAICreditsExceeded } = resolveAICreditsFailureState();
const inferenceAccessError = process.env.GH_AW_INFERENCE_ACCESS_ERROR === "true";
const copilotOrgBillingError = detectCopilotOrgBillingErrorFromLog();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Threaded in 8dc6865: copilotOrgBillingError now flows into buildFailureMatchCategories as copilot_org_billing_error (added to the schema filter pattern and the safe-outputs docs table) and into buildFailureIssueTitle. Tests assert the category replaces the agent_failure fallback and that the title is emitted.

@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 /codebase-design — requesting changes on two correctness/consistency gaps in the new Copilot org-billing detection.

📋 Key Themes & Highlights

Key Themes

  • Regex overlap risk: COPILOT_ORG_BILLING_ERROR_RE includes the generic Access denied by policy settings / invalid access to inference phrases, which are also the sole triggers for the existing engine-agnostic INFERENCE_ACCESS_ERROR_PATTERN. Combined with the loose COPILOT_ORG_BILLING_MODE_RE proxy-mode check, this can misclassify unrelated inference-access failures as organization-billing failures in copilot-requests: write runs, surfacing the wrong remediation.
  • Incomplete wiring: unlike every other specialized signal in this file (inferenceAccessError, mcpPolicyError, etc.), copilotOrgBillingError isn't threaded into buildFailureIssueTitle or buildFailureMatchCategories. The failure issue title and dedup marker will fall back to the generic "failed"/agent_failure category, weakening the specialized guidance this PR is meant to add.

Positive Highlights

  • ✅ Good test coverage for the three documented org-billing 403 signatures and the PAT-isolation negative case.
  • ✅ Correct suppression ordering — the new context takes priority over inferenceAccessErrorContext/credentialAuthErrorContext so guidance isn't duplicated.
  • ✅ Clear, actionable remediation template with concrete settings path and PAT fallback.

Warning

Firewall blocked 1 domain

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

  • registry.npmjs.org

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

network:
  allowed:
    - defaults
    - "registry.npmjs.org"

See Network Configuration for more information.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 108.9 AIC · ⌖ 15.2 AIC · ⊞ 10.4K
Comment /matt to run again

const ENGINE_MAX_RUNS_EXCEEDED_RE = /(?:\bmax_runs_exceeded\b|\bmaximum\s+llm\s+invocations\s+exceeded\b)/i;
const COPILOT_ORG_BILLING_MODE_RE = /API proxy enabled:[^\n]*Copilot=true \(github-token\)/i;
const COPILOT_ORG_BILLING_ERROR_RE =
/(?:awf-reflect: models fetch returned 403\b|Copilot requests authentication failed through the gh-aw API proxy \(HTTP 403\b|Authentication failed with provider at (?:https?:\/\/)?(?:api-proxy|(?:172\.(?:1[6-9]|2\d|3[01])|10|192\.168)\.\d+\.\d+)(?::\d+)?[^\n]*\(HTTP 403\)|Access denied by policy settings|invalid access to inference)/i;

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.

[/codebase-design] COPILOT_ORG_BILLING_ERROR_RE reuses the generic Access denied by policy settings / invalid access to inference phrases that already back INFERENCE_ACCESS_ERROR_PATTERN (used across all engines, not just Copilot-with-org-billing). Since COPILOT_ORG_BILLING_MODE_RE only checks that the proxy log mentions Copilot=true (github-token) — not that this specific error line is caused by billing — any generic inference-access rejection that happens to occur in a copilot-requests: write run will be misclassified as an organization-billing failure, showing the wrong remediation (org billing policy / PAT fallback) instead of the actual cause.

💡 Suggested fix

Drop the two generic phrases from COPILOT_ORG_BILLING_ERROR_RE and rely only on the three specific 403 signatures mentioned in the PR description (models fetch returned 403, Copilot requests authentication failed ... (HTTP 403, Authentication failed with provider at <proxy-host> ... (HTTP 403)). These are the actual reported signatures; the generic phrases were designed for a different failure class and their presence undermines the intended disambiguation between PAT failures and org-billing failures.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Dropped both generic phrases in 8dc6865. COPILOT_ORG_BILLING_ERROR_RE now matches only the three reported 403 signatures, and a test asserts that Access denied by policy settings / invalid access to inference are no longer classified as org-billing failures.

const timeoutMinutes = process.env.GH_AW_TIMEOUT_MINUTES || "";
const { aiCredits, maxAICredits, aiCreditsRateLimitError, maxAICreditsExceeded } = resolveAICreditsFailureState();
const inferenceAccessError = process.env.GH_AW_INFERENCE_ACCESS_ERROR === "true";
const copilotOrgBillingError = detectCopilotOrgBillingErrorFromLog();

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.

[/codebase-design] copilotOrgBillingError is computed and used to suppress inferenceAccessErrorContext/credentialAuthErrorContext, but it is never added to buildFailureMatchCategories(...) or buildFailureIssueTitle(...) (both called around line 3864-3920). Every other specialized failure signal in this file (inferenceAccessError, mcpPolicyError, modelNotSupportedError, etc.) flows into both the title and the dedup category list.

💡 Impact & suggested fix

Without this wiring:

  • The failure issue title falls back to the generic [aw] {workflow} failed instead of a specific org-billing title.
  • failureCategories won't include an copilot_org_billing_error entry, so the dedup marker can't distinguish this failure from a generic agent_failure, and future runs may not reuse/close the right issue.

Add copilotOrgBillingError as an option to both buildFailureIssueTitle (e.g. a title like [aw] {workflow} hit Copilot organization billing error) and buildFailureMatchCategories (e.g. copilot_org_billing_error category), mirroring how inferenceAccessError is threaded through.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Wired in 8dc6865: copilotOrgBillingError is now passed to both buildFailureIssueTitle ([aw] {workflow} hit Copilot organization billing error) and buildFailureMatchCategories (copilot_org_billing_error), mirroring inferenceAccessError. The category is also allowed by the safe-outputs schema pattern and documented.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@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.

Reviewed with Impeccable clarify (docs/copy-focused change) since this PR is primarily new error-guidance markdown and detection logic, no UI. No blocking issues found.

What I checked:

  • COPILOT_ORG_BILLING_MODE_RE + COPILOT_ORG_BILLING_ERROR_RE gating: correctly requires both the github-token proxy mode marker and one of the known 403/policy signatures, so PAT-based failures (no github-token mode line) are not misclassified — verified via the added test cases.
  • detectCopilotOrgBillingErrorFromLog is gated on GH_AW_ENGINE_ID === "copilot", consistent with other engine-specific detectors in this file.
  • New context is correctly wired to suppress the now-superseded inference_access_error_context and credential_auth_error_context in both call sites, avoiding duplicate/conflicting guidance in the rendered comment.
  • Copy in copilot_org_billing_error.md is clear, actionable, and gives two concrete remediation paths (org policy toggle vs. PAT fallback) with a doc link, matching the tone of sibling templates like credential_auth_error.md and inference_access_error.md.
  • Ran the new buildCopilotOrgBillingErrorContext / detectCopilotOrgBillingErrorFromLog test suite locally — all 6 new tests pass.
  • Template wiring in agent_failure_comment.md / agent_failure_issue.md placeholders looks correct and ordered sensibly (before the generic credential/inference contexts it supersedes).

No actionable issues found — approving.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 124.2 AIC · ⌖ 12.6 AIC · ⊞ 8.4K

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
pelikhan merged commit c3dcc77 into main Sep 14, 2026
44 checks passed
@pelikhan
pelikhan deleted the copilot/handle-special-errors branch September 14, 2026 17:17
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.

3 participants