{"record":{"id":"6c1e5b7f53387a0b","repo":"Aider-AI/aider","slug":"github-copilot-token-environment-variable-not-foun","errorCode":null,"errorMessage":"GITHUB_COPILOT_TOKEN environment variable not found","messagePattern":"GITHUB_COPILOT_TOKEN environment variable not found","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"critical","filePath":"aider/models.py","lineNumber":952,"sourceCode":"    def github_copilot_token_to_open_ai_key(self, extra_headers):\n        # check to see if there's an openai api key\n        # If so, check to see if it's expire\n        openai_api_key = \"OPENAI_API_KEY\"\n\n        if openai_api_key not in os.environ or (\n            int(dict(x.split(\"=\") for x in os.environ[openai_api_key].split(\";\"))[\"exp\"])\n            < int(datetime.now().timestamp())\n        ):\n            import requests\n\n            class GitHubCopilotTokenError(Exception):\n                \"\"\"Custom exception for GitHub Copilot token-related errors.\"\"\"\n\n                pass\n\n            # Validate GitHub Copilot token exists\n            if \"GITHUB_COPILOT_TOKEN\" not in os.environ:\n                raise KeyError(\"GITHUB_COPILOT_TOKEN environment variable not found\")\n\n            github_token = os.environ[\"GITHUB_COPILOT_TOKEN\"]\n            if not github_token.strip():\n                raise KeyError(\"GITHUB_COPILOT_TOKEN environment variable is empty\")\n\n            headers = {\n                \"Authorization\": f\"Bearer {os.environ['GITHUB_COPILOT_TOKEN']}\",\n                \"Editor-Version\": extra_headers[\"Editor-Version\"],\n                \"Copilot-Integration-Id\": extra_headers[\"Copilot-Integration-Id\"],\n                \"Content-Type\": \"application/json\",\n            }\n\n            url = \"https://api.github.com/copilot_internal/v2/token\"\n            res = requests.get(url, headers=headers)\n            if res.status_code != 200:\n                safe_headers = {k: v for k, v in headers.items() if k != \"Authorization\"}\n                token_preview = github_token[:5] + \"...\" if len(github_token) >= 5 else github_token\n                safe_headers[\"Authorization\"] = f\"Bearer {token_preview}\"","sourceCodeStart":934,"sourceCodeEnd":970,"githubUrl":"https://github.com/Aider-AI/aider/blob/5dc9490bb35f9729ef2c95d00a19ccd30c26339c/aider/models.py#L934-L970","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","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.","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."],"exampleFix":"# before\n$ aider --model github/copilot-codex  # KeyError: GITHUB_COPILOT_TOKEN environment variable not found\n\n# after\n$ export GITHUB_COPILOT_TOKEN=\"gho_xxx...\"\n$ aider --model github/copilot-codex","handlingStrategy":"validation","validationCode":"import os\n\ndef copilot_env_ready():\n    \"\"\"Check GitHub Copilot prerequisites without leaking the token.\"\"\"\n    tok = os.environ.get(\"GITHUB_COPILOT_TOKEN\")\n    return bool(tok and tok.strip())","typeGuard":null,"tryCatchPattern":"try:\n    resp = model.send_completion(messages, functions=None, stream=False)\nexcept KeyError as e:\n    if str(e).find(\"GITHUB_COPILOT_TOKEN\") != -1:\n        raise SystemExit(\"Export GITHUB_COPILOT_TOKEN (device-code flow) and retry.\")\n    raise","preventionTips":["Assert GITHUB_COPILOT_TOKEN is present and non-blank at process start before any Copilot model call.","Inject the variable via your secrets manager (CI secret, systemd Environment=, docker -e) rather than shell rc files.","Remember the check fires lazily when the cached token expires — keep the env var available for the whole session."],"tags":["authentication","environment-variables","github-copilot","credentials","aider"],"backgroundTag":null,"analyzedSha":"5dc9490bb35f9729ef2c95d00a19ccd30c26339c","analyzedAt":"2026-08-15T05:40:10.498Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}