anomalyco / anomalyco/opencode
v2: recover integration credentials after 401/403 responses
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
- Authenticate a V2 OAuth integration such as GitHub Copilot.
- Allow the stored credential, authorization state, or account-specific endpoint metadata to become stale or invalid.
- Make a provider request that returns HTTP 401 or an integration-recoverable HTTP 403.
- 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.tsclassifies 401/403 responses.packages/core/src/session/runner/retry.tsmarks authentication failures as non-retryable.packages/core/src/integration.tsrefreshes expiring credentials during connection resolution.packages/core/src/plugin/provider/github-copilot.tssupplies 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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