Skip to content

GitHub Copilot preview models rejected — auth plugin sends raw OAuth token instead of exchanging for Copilot session token #19338

Closed

Description

@ben-vargas

Description

Preview models on the GitHub Copilot API (e.g. claude-opus-4.6-fast) fail with 400 model_not_supported when used through opencode, despite being valid and available on the Copilot API.

There are three interconnected issues in the copilot auth plugin (src/plugin/copilot.ts):

1. Wrong OAuth App for device flow

The plugin uses OAuth App client ID Ov23li8tweQw6odWQebz, which produces gho_ tokens. The Copilot session token exchange endpoint (/copilot_internal/v2/token) only accepts GitHub App user tokens (ghu_). The correct client ID is Iv1.b507a08c87ecfe98 (the GitHub Copilot CLI GitHub App), which other Copilot integrations use.

2. No session token exchange

The raw GitHub token is sent directly as the Authorization: Bearer header (line 126). This works for GA models but the Copilot API rejects preview models unless a proper Copilot session token (tid=...) is used, obtained via a GET to /copilot_internal/v2/token with Authorization: token <github_token>.

3. Missing Copilot integration headers on API requests

The fetch wrapper doesn't include Editor-Version, Editor-Plugin-Version, or Copilot-Integration-Id headers on API requests. The session token is scoped to the integration specified during the exchange, and the API returns 403 Forbidden: token not authorized for this integration if these headers are missing or mismatched.

Evidence

Tested by hitting the Copilot API endpoint (POST /chat/completions) with different token and header combinations:

Token type Headers claude-opus-4.6 (GA) claude-opus-4.6-fast (preview)
Raw gho_ (OAuth App) No integration headers ✅ 200 ❌ 400 model_not_supported
Raw ghu_ (GitHub App) No integration headers ✅ 200 ❌ 400 model_not_supported
Session token tid=... With integration headers ✅ 200 ✅ 200
Session token tid=... No integration headers ❌ 403 token not authorized ❌ 403 token not authorized

The token exchange endpoint itself:

Token type Auth scheme Result
gho_ (OAuth App) Bearer or token ❌ 404
ghu_ (GitHub App) token ✅ 200

Steps to reproduce

  1. Log in to GitHub Copilot in opencode via the device flow
  2. Add a preview model to opencode.jsonc:
    "provider": {
      "github-copilot": {
        "models": {
          "claude-opus-4.6-fast": {
            "name": "Claude Opus 4.6 (fast mode)",
            "reasoning": true,
            "limit": { "context": 200000, "output": 64000 }
          }
        }
      }
    }
  3. Select claude-opus-4.6-fast as the model
  4. Send any message

Expected: Model responds normally
Actual: The requested model is not supported.

Plugins

No response

OpenCode version

Latest dev branch

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Mar 26, 2026
  2. github-actions commented on Mar 26, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  3. rekram1-node commented on Apr 9, 2026

    @rekram1-node
    Contributor
    1. Wrong OAuth App for device flow

    Incorrect, we have our own oauth app and we are required to use it.

  4. ben-vargas commented on Apr 9, 2026

    @ben-vargas
    ContributorAuthor
    1. Wrong OAuth App for device flow

    Incorrect, we have our own oauth app and we are required to use it.

    If that's the only one Anomaly has, it does not work for exchanging ghu_ tokens, so what this PR is trying to achieve doesn't sound possible with the Anomaly Client ID and this can probably be closed.

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

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions