Aider-AI/aider · critical · KeyError

GITHUB_COPILOT_TOKEN environment variable not found

Error message

GITHUB_COPILOT_TOKEN environment variable not found

What it means

In aider/models.py, the GitHub Copilot provider path exchanges a GitHub token for a short-lived Copilot OpenAI-compatible token via the github/copilot_internal/v2/token API. Before making that request it requires the GITHUB_COPILOT_TOKEN environment variable to hold your GitHub OAuth token; if the variable is absent from os.environ it raises KeyError('GITHUB_COPILOT_TOKEN environment variable not found'). This is a missing-credential configuration error raised lazily, at first model use.

Source

Thrown at aider/models.py:952

    def github_copilot_token_to_open_ai_key(self, extra_headers):
        # check to see if there's an openai api key
        # If so, check to see if it's expire
        openai_api_key = "OPENAI_API_KEY"

        if openai_api_key not in os.environ or (
            int(dict(x.split("=") for x in os.environ[openai_api_key].split(";"))["exp"])
            < int(datetime.now().timestamp())
        ):
            import requests

            class GitHubCopilotTokenError(Exception):
                """Custom exception for GitHub Copilot token-related errors."""

                pass

            # Validate GitHub Copilot token exists
            if "GITHUB_COPILOT_TOKEN" not in os.environ:
                raise KeyError("GITHUB_COPILOT_TOKEN environment variable not found")

            github_token = os.environ["GITHUB_COPILOT_TOKEN"]
            if not github_token.strip():
                raise KeyError("GITHUB_COPILOT_TOKEN environment variable is empty")

            headers = {
                "Authorization": f"Bearer {os.environ['GITHUB_COPILOT_TOKEN']}",
                "Editor-Version": extra_headers["Editor-Version"],
                "Copilot-Integration-Id": extra_headers["Copilot-Integration-Id"],
                "Content-Type": "application/json",
            }

            url = "https://api.github.com/copilot_internal/v2/token"
            res = requests.get(url, headers=headers)
            if res.status_code != 200:
                safe_headers = {k: v for k, v in headers.items() if k != "Authorization"}
                token_preview = github_token[:5] + "..." if len(github_token) >= 5 else github_token
                safe_headers["Authorization"] = f"Bearer {token_preview}"

View on GitHub (pinned to 5dc9490bb3)

Solutions

  1. Obtain a GitHub Copilot OAuth token (e.g. via the device-code flow used by Copilot tooling) and export it: export GITHUB_COPILOT_TOKEN=<token> before launching aider.
  2. If it worked earlier in a session and failed later, the cached Copilot token expired and the refresh needs the env var — re-export it and retry; the code caches the refreshed token back into the openai_api_key env slot.
  3. For service/CI usage, inject GITHUB_COPILOT_TOKEN into the process environment (systemd Environment=, docker -e, CI secret) rather than relying on shell rc files.

Example fix

# before
$ aider --model github/copilot-codex  # KeyError: GITHUB_COPILOT_TOKEN environment variable not found

# after
$ export GITHUB_COPILOT_TOKEN="gho_xxx..."
$ aider --model github/copilot-codex
Defensive patterns

Strategy: validation

Validate before calling

import os

def copilot_env_ready():
    """Check GitHub Copilot prerequisites without leaking the token."""
    tok = os.environ.get("GITHUB_COPILOT_TOKEN")
    return bool(tok and tok.strip())

Try / catch

try:
    resp = model.send_completion(messages, functions=None, stream=False)
except KeyError as e:
    if str(e).find("GITHUB_COPILOT_TOKEN") != -1:
        raise SystemExit("Export GITHUB_COPILOT_TOKEN (device-code flow) and retry.")
    raise

Prevention

When it happens

Trigger: Configuring a model whose prefix routes to the GitHub Copilot provider (aider's Copilot model entries) while GITHUB_COPILOT_TOKEN is not exported in the shell/process environment. The check also only runs when the cached token in the openai_api_key env slot is expired (its 'exp' claim is in the past), so the error can appear mid-session after a previously cached token expires.

Common situations: Using aider with GitHub Copilot models without having run a device-code login flow that exports GITHUB_COPILOT_TOKEN; running under a service/scheduler/cron where the interactive shell's env vars were not inherited; or a new terminal where the export only lives in another shell profile.

Related errors


AI-assisted analysis of Aider-AI/aider@5dc9490bb3 (2026-08-15). Data as JSON: /api/errors/6c1e5b7f53387a0b. Report an issue: GitHub.