{"record":{"id":"1027b2d1716c947d","repo":"BerriAI/litellm","slug":"str-e-1027b2","errorCode":null,"errorMessage":"str(e)","messagePattern":"str\\(e\\)","errorType":"exception","errorClass":"AuthenticationError","httpStatus":401,"severity":"critical","filePath":"litellm/llms/github_copilot/embedding/transformation.py","lineNumber":83,"sourceCode":"            if not api_key:\n                raise AuthenticationError(\n                    model=model,\n                    llm_provider=\"github_copilot\",\n                    message=\"GitHub Copilot API key is required. Please authenticate via OAuth Device Flow.\",\n                )\n\n            # Get default headers\n            default_headers: Final = get_copilot_default_headers(api_key)\n\n            # Merge with existing headers (user's extra_headers take priority)\n            merged_headers: Final = {**default_headers, **headers}\n\n            verbose_logger.debug(\"GitHub Copilot Embedding 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        api_key: str | None,\n        model: str,\n        optional_params: dict,\n        litellm_params: dict,\n        stream: bool | None = None,\n    ) -> str:\n        \"\"\"\n        Get the complete URL for GitHub Copilot Embedding API endpoint.\n        \"\"\"\n        # Use provided api_base or fall back to authenticator's base or default","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/github_copilot/embedding/transformation.py#L65-L101","documentation":"Raised in the embedding transformation when self.authenticator.get_api_key() throws GetAPIKeyError; it is wrapped as AuthenticationError with str(e) as the message. Identical pattern to the chat path (error 1630) but reached via litellm.embedding or aembedding with a github_copilot model. The embedded string identifies the underlying authenticator failure (missing token on refresh, save failure, or refresh-retries-exhausted).","triggerScenarios":"litellm.embedding(..., model=\"github_copilot/...\") before any successful device-flow login, or when the cached access token expired and refresh fails (401), the cache dir is unwritable (500 'Failed to save API key'), or the refresh response lacks 'token'.","commonSituations":"Embedding-only workloads assuming an api_key parameter works like OpenAI (Copilot ignores caller api_key and always uses OAuth); ephemeral CI losing the token cache; orgs disabling Copilot embedding models so refresh returns errors.","solutions":["Follow the embedded message to the root cause — complete the device-flow login if none exists, or fix the cache/refresh failure it names.","Make the token cache directory writable and persistent for the service account running embeddings.","Warm the authenticator with one interactive call after deployment so the cache is populated before headless embedding jobs.","Confirm your Copilot entitlement covers the embedding model requested."],"exampleFix":"# before: embedding call on a fresh server -> AuthenticationError (str of GetAPIKeyError)\nlitellm.embedding(model=\"github_copilot/text-embedding-3-small\", input=[\"hello\"])\n\n# after: guard with a startup pre-flight so failures surface at boot, not mid-request\nfrom litellm.llms.github_copilot.authenticator import GitHubCopilotAuthenticator\ntry:\n    GitHubCopilotAuthenticator().get_api_key()\nexcept Exception as e:\n    raise SystemExit(f\"Run 'litellm --login github_copilot' on this host: {e}\")\nlitellm.embedding(model=\"github_copilot/text-embedding-3-small\", 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 embeddings unavailable: {e} — complete device-flow login first\")","typeGuard":null,"tryCatchPattern":"from litellm.exceptions import AuthenticationError\n\ntry:\n    emb = litellm.embedding(model=\"github_copilot/text-embedding-3-small\", input=texts)\nexcept AuthenticationError as e:\n    msg = str(e)\n    if \"Failed to save API key\" in msg:\n        fix_token_dir_permissions(); retry_once()\n    elif \"maximum retries\" in msg or \"refresh\" in msg:\n        raise SystemExit(\"Re-authenticate Copilot (device flow) before resuming embeddings\") from e\n    else:\n        raise","preventionTips":["Warm Copilot auth with one call at deployment time, not mid-batch.","Remember github_copilot ignores caller api_key — OAuth is the only credential path.","Persist and probe the token dir in deployment checks.","Route embedding jobs through a startup gate that verifies get_api_key()."],"tags":["github-copilot","embedding","authentication","oauth","wrapper"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}