{"record":{"id":"38abeb2eb41c1667","repo":"BerriAI/litellm","slug":"str-e-38abeb","errorCode":null,"errorMessage":"str(e)","messagePattern":"str\\(e\\)","errorType":"exception","errorClass":"AuthenticationError","httpStatus":401,"severity":"critical","filePath":"litellm/llms/github_copilot/responses/transformation.py","lineNumber":237,"sourceCode":"            input_param: Final = self._get_input_from_params(litellm_params)\n\n            # Add X-Initiator header based on input analysis\n            if input_param is not None:\n                initiator: Final = self._get_initiator(input_param)\n                merged_headers[\"X-Initiator\"] = initiator\n                verbose_logger.debug(\"GitHub Copilot Responses API: Set X-Initiator=%s\", initiator)\n\n                # Add vision header if input contains images\n                if self._has_vision_input(input_param):\n                    merged_headers[\"copilot-vision-request\"] = \"true\"\n                    verbose_logger.debug(\"GitHub Copilot Responses API: Enabled vision request\")\n\n            verbose_logger.debug(\"GitHub Copilot Responses API: Successfully configured headers for model %s\", model)\n\n            return merged_headers\n\n        except GetAPIKeyError as e:\n            raise AuthenticationError(\n                model=model,\n                llm_provider=\"github_copilot\",\n                message=str(e),\n            )\n\n    def get_complete_url(\n        self,\n        api_base: str | None,\n        litellm_params: dict,\n    ) -> str:\n        \"\"\"\n        Get the complete URL for GitHub Copilot Responses API endpoint.\n        \"\"\"\n        # Use provided api_base or fall back to authenticator's base or default\n        effective_api_base = (\n            api_base\n            or self.authenticator.get_api_base()\n            or os.getenv(\"GITHUB_COPILOT_API_BASE\")","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/github_copilot/responses/transformation.py#L219-L255","documentation":"Raised in the responses transformation when get_api_key() throws GetAPIKeyError; re-wrapped as AuthenticationError with str(e) as the message. Same pass-through pattern as 1630/1632/1633, hit from the responses API path. The embedded string names the real authenticator failure (refresh exhausted, missing token in refresh response, or cache save OSError).","triggerScenarios":"litellm.responses(model=\"github_copilot/...\", ...) with no completed OAuth login, an expired access token that fails refresh across retries, an unwritable token cache directory, or refresh responses consistently lacking 'token'.","commonSituations":"New deployments skipping the interactive OAuth step; long-running services whose cached access token outlived its refresh window; containerized runs with root-owned or read-only token dirs; GitHub Copilot entitlement lapsing.","solutions":["Decode str(e) to find the root failure and fix it (re-login, cache permissions, entitlement).","Run the device-flow login once per host and persist the token cache volume.","Add a boot-time pre-flight call (get_api_key) so auth failures crash deployment, not user requests.","Upgrade litellm to keep the Copilot authenticator aligned with GitHub's current token endpoints."],"exampleFix":"# before: responses call before OAuth done\nlitellm.responses(model=\"github_copilot/gpt-4o\", input=\"hello\")\n# AuthenticationError: Failed to refresh API key after maximum retries\n\n# after: startup gate + authenticated runtime\nfrom litellm.llms.github_copilot.authenticator import GitHubCopilotAuthenticator\ntry:\n    GitHubCopilotAuthenticator().get_api_key()\nexcept Exception as e:\n    raise SystemExit(f\"Copilot auth not ready: {e}\")\nlitellm.responses(model=\"github_copilot/gpt-4o\", input=\"hello\")","handlingStrategy":"try-catch","validationCode":"from litellm.llms.github_copilot.authenticator import GitHubCopilotAuthenticator\n\ntry:\n    GitHubCopilotAuthenticator().get_api_key()\nexcept Exception as e:\n    raise SystemExit(f\"github_copilot responses API unavailable: {e}\")","typeGuard":null,"tryCatchPattern":"from litellm.exceptions import AuthenticationError\n\ntry:\n    resp = litellm.responses(model=\"github_copilot/gpt-4o\", input=\"hello\")\nexcept AuthenticationError as e:\n    msg = str(e)\n    if \"save API key\" in msg:\n        fix_token_dir_permissions(); resp = litellm.responses(model=\"github_copilot/gpt-4o\", input=\"hello\")\n    elif \"missing token\" in msg:\n        clear_copilot_cache(); raise SystemExit(\"Re-run copilot login after cache clear\") from e\n    else:\n        raise","preventionTips":["Gate serving on a boot-time get_api_key() check.","Map each embedded cause to a runbook step (permissions vs re-login vs upgrade).","Persist token caches across container restarts.","Track litellm releases for Copilot authenticator fixes."],"tags":["github-copilot","responses-api","authentication","oauth","wrapper"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}