Aider-AI/aider · critical · KeyError

GITHUB_COPILOT_TOKEN environment variable is empty

Error message

GITHUB_COPILOT_TOKEN environment variable is empty

What it means

Companion check to the missing-variable error in aider/models.py: GITHUB_COPILOT_TOKEN exists in the environment but its value is empty or whitespace-only (github_token.strip() is falsy). It raises KeyError('GITHUB_COPILOT_TOKEN environment variable is empty'). The distinction matters diagnostically: the variable is exported but holds no usable credential — typically an empty-string assignment or a botched copy/paste into a dotfile.

Source

Thrown at aider/models.py:956

        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}"
                raise GitHubCopilotTokenError(
                    f"GitHub Copilot API request failed (Status: {res.status_code})\n"
                    f"URL: {url}\n"
                    f"Headers: {json.dumps(safe_headers, indent=2)}\n"

View on GitHub (pinned to 5dc9490bb3)

Solutions

  1. Check the current value without printing it: [ -n "$GITHUB_COPILOT_TOKEN" ] && echo set || echo empty — then re-export the real token.
  2. Search shell rc files and .env files for an empty assignment to GITHUB_COPILOT_TOKEN and fix or remove the placeholder line.
  3. In CI, verify the secret is actually attached to the job and non-empty before invoking aider.

Example fix

# before
export GITHUB_COPILOT_TOKEN=

# after
export GITHUB_COPILOT_TOKEN="$(cat ~/.config/aider/copilot_token)"  # real token
# verify without exposing the value:
[ -n "$GITHUB_COPILOT_TOKEN" ] && echo "token set"
Defensive patterns

Strategy: validation

Validate before calling

import os

def assert_copilot_token_nonempty():
    tok = os.environ.get("GITHUB_COPILOT_TOKEN", "")
    if not tok.strip():
        raise SystemExit(
            "GITHUB_COPILOT_TOKEN is empty. Re-export a real token:\n"
            "  export GITHUB_COPILOT_TOKEN=<token>"
        )

Try / catch

try:
    result = model.simple_send_with_retries(msgs)
except KeyError as e:
    if "GITHUB_COPILOT_TOKEN" in str(e):
        # covers both 'not found' and 'is empty' variants
        print("Copilot credential missing/empty — fix env and retry")
    raise

Prevention

When it happens

Trigger: Running with a Copilot model after 'export GITHUB_COPILOT_TOKEN=' (empty assignment), setting it to ''/' ' in a .env-style loader, or a CI secret that was defined with no value. Triggered at first Copilot model call whose cached token is expired, same lazy path as the missing-variable check.

Common situations: Dotfiles with a placeholder line like export GITHUB_COPILOT_TOKEN= awaiting manual fill-in; docker-compose environment entries mapping an unset CI variable; secrets managers returning empty strings for unset keys.

Related errors


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