BerriAI/litellm · critical · AuthenticationError

str(e)

Error message

str(e)

What it means

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).

Source

Thrown at litellm/llms/github_copilot/embedding/transformation.py:83

            if not api_key:
                raise AuthenticationError(
                    model=model,
                    llm_provider="github_copilot",
                    message="GitHub Copilot API key is required. Please authenticate via OAuth Device Flow.",
                )

            # Get default headers
            default_headers: Final = get_copilot_default_headers(api_key)

            # Merge with existing headers (user's extra_headers take priority)
            merged_headers: Final = {**default_headers, **headers}

            verbose_logger.debug("GitHub Copilot Embedding API: Successfully configured headers for model %s", model)

            return merged_headers

        except GetAPIKeyError as e:
            raise AuthenticationError(
                model=model,
                llm_provider="github_copilot",
                message=str(e),
            )

    def get_complete_url(
        self,
        api_base: str | None,
        api_key: str | None,
        model: str,
        optional_params: dict,
        litellm_params: dict,
        stream: bool | None = None,
    ) -> str:
        """
        Get the complete URL for GitHub Copilot Embedding API endpoint.
        """
        # Use provided api_base or fall back to authenticator's base or default

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Follow the embedded message to the root cause — complete the device-flow login if none exists, or fix the cache/refresh failure it names.
  2. Make the token cache directory writable and persistent for the service account running embeddings.
  3. Warm the authenticator with one interactive call after deployment so the cache is populated before headless embedding jobs.
  4. Confirm your Copilot entitlement covers the embedding model requested.

Example fix

# before: embedding call on a fresh server -> AuthenticationError (str of GetAPIKeyError)
litellm.embedding(model="github_copilot/text-embedding-3-small", input=["hello"])

# after: guard with a startup pre-flight so failures surface at boot, not mid-request
from litellm.llms.github_copilot.authenticator import GitHubCopilotAuthenticator
try:
    GitHubCopilotAuthenticator().get_api_key()
except Exception as e:
    raise SystemExit(f"Run 'litellm --login github_copilot' on this host: {e}")
litellm.embedding(model="github_copilot/text-embedding-3-small", input=["hello"])
Defensive patterns

Strategy: try-catch

Validate before calling

from litellm.llms.github_copilot.authenticator import GitHubCopilotAuthenticator

try:
    GitHubCopilotAuthenticator().get_api_key()
except Exception as e:
    raise SystemExit(f"github_copilot embeddings unavailable: {e} — complete device-flow login first")

Try / catch

from litellm.exceptions import AuthenticationError

try:
    emb = litellm.embedding(model="github_copilot/text-embedding-3-small", input=texts)
except AuthenticationError as e:
    msg = str(e)
    if "Failed to save API key" in msg:
        fix_token_dir_permissions(); retry_once()
    elif "maximum retries" in msg or "refresh" in msg:
        raise SystemExit("Re-authenticate Copilot (device flow) before resuming embeddings") from e
    else:
        raise

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

Related errors


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