BerriAI/litellm · critical · AuthenticationError

str(e)

Error message

str(e)

What it means

Raised in the chat transformation's validate_environment when self.authenticator.get_api_key() throws GetAPIKeyError; it is re-raised as a litellm AuthenticationError whose message is str(e) of the original (e.g. 'API key response missing token', 'Failed to refresh API key: ...', or the save-failure variant). This is a pass-through wrapper: the root cause is always one of the authenticator failures (errors 1626/1627/1628/1629/1631 upstream).

Source

Thrown at litellm/llms/github_copilot/chat/transformation.py:47

        self.authenticator = Authenticator()

    def _get_openai_compatible_provider_info(
        self,
        model: str,
        api_base: str | None,
        api_key: str | None,
        custom_llm_provider: str,
    ) -> tuple[str | None, str | None, str]:
        dynamic_api_base: Final = (
            api_base
            or self.authenticator.get_api_base()
            or os.getenv("GITHUB_COPILOT_API_BASE")
            or DEFAULT_GITHUB_COPILOT_API_BASE
        )
        try:
            dynamic_api_key: Final = self.authenticator.get_api_key()
        except GetAPIKeyError as e:
            raise AuthenticationError(
                model=model,
                llm_provider=custom_llm_provider,
                message=str(e),
            )
        return dynamic_api_base, dynamic_api_key, custom_llm_provider

    def _transform_messages(
        self,
        messages,
        model: str,
    ):
        import litellm

        # Check if system-to-assistant conversion is disabled
        if litellm.disable_copilot_system_to_assistant:
            # GitHub Copilot API now supports system prompts for all models (Claude, GPT, etc.)
            # No conversion needed - just return messages as-is
            return messages

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Read the embedded message: it names the real failure (refresh failed / missing token / save failed) — fix that underlying cause using the corresponding guidance.
  2. For first-time/unauthenticated setups, complete the OAuth device flow interactively once and ship the resulting token cache to the server.
  3. Ensure the token cache directory exists, is writable, and persists across restarts.
  4. Upgrade litellm if the message indicates response-shape problems ('missing token'), since the authenticator tracks GitHub's internal endpoints.

Example fix

# before: fresh deployment, no cached Copilot credentials
litellm.completion(model="github_copilot/gpt-4o", messages=[{"role": "user", "content": "hi"}])
# AuthenticationError: (missing/failed key via str(e))

# after: pre-flight the authenticator before first request
from litellm.llms.github_copilot.authenticator import GitHubCopilotAuthenticator
auth = GitHubCopilotAuthenticator()
try:
    auth.get_api_key()
except Exception as e:
    raise SystemExit(f"Complete GitHub Copilot login first: {e}")
litellm.completion(model="github_copilot/gpt-4o", messages=[{"role": "user", "content": "hi"}])
Defensive patterns

Strategy: try-catch

Validate before calling

from litellm.llms.github_copilot.authenticator import GitHubCopilotAuthenticator

try:
    key = GitHubCopilotAuthenticator().get_api_key()
    assert key, "empty key returned"
except Exception as e:
    raise SystemExit(f"github_copilot chat unavailable — authenticate first: {e}")

Try / catch

from litellm.exceptions import AuthenticationError

try:
    resp = litellm.completion(model="github_copilot/gpt-4o", messages=msgs)
except AuthenticationError as e:
    # str(e) carries the root cause: refresh failed / missing token / save failed
    if "Failed to save API key" in str(e):
        fix_token_dir_permissions()  # infra fix, then retry
    else:
        raise SystemExit(f"Copilot auth needs operator action: {e}") from e

Prevention

When it happens

Trigger: Any litellm.completion(..., model="github_copilot/...") call where the Copilot key pipeline fails: no completed device-flow login, expired/revoked access token that cannot refresh, unwritable token cache, or a refresh response missing the token field. The str(e) message identifies which sub-failure fired.

Common situations: First-ever use on a machine without cached Copilot credentials; headless servers where the OAuth flow was never completed; CI jobs with ephemeral home dirs losing the token cache; token cache dir made read-only in hardened container images.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/bd8480b16ea3b527. Report an issue: GitHub.