anomalyco / anomalyco/opencode

v2: recover integration credentials after 401/403 responses

Open
#38,203 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Summary

V2 classifies provider HTTP 401/403 responses as authentication errors but does not connect those failures back to the credential or integration that authorized the request. GitHub Copilot and potentially other OAuth integrations need a consistent way to invalidate or refresh credentials, update derived endpoint metadata, and safely retry after an authentication rejection.

Environment

  • opencode version: v0.0.0-next-15919
  • OS: Darwin 25.5.0, arm64
  • Terminal: Ghostty, TERM=xterm-256color, COLORTERM=truecolor
  • Shell: /bin/zsh
  • Install/channel: next, local V2 development
  • Active plugins: caffeinate.ts, plugin.ts

Reproduction

  1. Authenticate a V2 OAuth integration such as GitHub Copilot.
  2. Allow the stored credential, authorization state, or account-specific endpoint metadata to become stale or invalid.
  3. Make a provider request that returns HTTP 401 or an integration-recoverable HTTP 403.
  4. Observe that the request fails without invalidating or refreshing the credential, rediscovering integration metadata, or retrying the request.

Expected Behavior

V2 should have a consistent status-aware credential recovery path that retains the identity of the integration connection used for each provider request.

  • A 401 should invalidate or refresh the associated credential when the integration supports recovery.
  • A 403 should invoke integration-specific policy because it may represent either recoverable stale authorization state or a permanent permission denial.
  • Successful refreshes and metadata changes should be persisted to the same credential.
  • GitHub Copilot recovery should also rediscover account-specific API endpoint metadata when appropriate.
  • The failed provider request should be retried at most once after successful recovery.
  • Concurrent failures for one credential should share a single recovery operation.
  • Unsupported or failed recovery should surface a clear reauthentication requirement without retry loops.
  • Existing OAuth integrations should be audited for the same behavior.

Actual Behavior

V2 currently only classifies these responses:

  • HTTP 401 becomes Authentication(kind: "invalid").
  • HTTP 403 becomes Authentication(kind: "insufficient-permissions").
  • Authentication failures are explicitly non-retryable.

Integration.connection.resolve refreshes only from stored expiration and only when the integration defines a refresh implementation. Provider status failures are not connected back to credential invalidation or refresh. GitHub Copilot's request wrapper does not inspect 401/403 responses and its OAuth method does not define refresh behavior.

Additional Context

Relevant V2 areas:

  • packages/ai/src/provider-error.ts classifies 401/403 responses.
  • packages/core/src/session/runner/retry.ts marks authentication failures as non-retryable.
  • packages/core/src/integration.ts refreshes expiring credentials during connection resolution.
  • packages/core/src/plugin/provider/github-copilot.ts supplies the stored OAuth credential to provider requests without status-aware recovery.

This should be designed as integration-aware recovery rather than a global unconditional retry for every 403 response.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing provider error classification in packages/ai/src/provider-error.ts through packages/core/src/session/runner/retry.ts and integration resolution in packages/core/src/integration.ts. Then inspect packages/core/src/plugin/provider/github-copilot.ts and its OAuth flow. Done means the listed recovery, persistence, retry, concurrency, and reauthentication behaviors are designed and implemented consistently for existing OAuth integrations.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authentication, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.