affaan-m/ECC · critical · AuthenticationError
{msg}
Error message
{msg} What it means
OpenAIProvider.generate() raises AuthenticationError when the caught exception message contains '401' or 'authentication'. The OpenAI client is constructed with _enforce_credentials=False, so it builds happily even with an empty/missing key and fails later at request time. For the official SDK this maps to an invalid, expired, or revoked key, or a request to a model/endpoint the key's project cannot access.
Source
Thrown at src/llm/providers/openai.py:117
usage = None
if response.usage:
usage = {
"prompt_tokens": response.usage.prompt_tokens,
"completion_tokens": response.usage.completion_tokens,
"total_tokens": response.usage.total_tokens,
}
return LLMOutput(
content=choice.message.content or "",
tool_calls=tool_calls,
model=response.model,
usage=usage,
stop_reason=choice.finish_reason,
)
except Exception as e:
msg = str(e)
if "401" in msg or "authentication" in msg.lower():
raise AuthenticationError(msg, provider=ProviderType.OPENAI) from e
if "429" in msg or "rate_limit" in msg.lower():
raise RateLimitError(msg, provider=ProviderType.OPENAI) from e
if "context" in msg.lower() and "length" in msg.lower():
raise ContextLengthError(msg, provider=ProviderType.OPENAI) from e
raise
def list_models(self) -> list[ModelInfo]:
return self._models.copy()
def validate_config(self) -> bool:
return bool(self.client.api_key)
def get_default_model(self) -> str:
return "gpt-4o-mini"
View on GitHub (pinned to 01e15490f0)
Solutions
- Verify OPENAI_API_KEY is set and call provider.validate_config() (returns True when the key is non-empty) before generate().
- Regenerate the key in the OpenAI dashboard and rotate the stored secret.
- Confirm the key's project can access the requested model.
- If using base_url for a proxy, supply the proxy's required auth, not the OpenAI key.
Example fix
// before
provider = OpenAIProvider()
output = provider.generate(llm_input)
// after
import os
from llm.core.interface import AuthenticationError
if not os.environ.get("OPENAI_API_KEY"):
raise SystemExit("Set OPENAI_API_KEY")
provider = OpenAIProvider()
assert provider.validate_config(), "OpenAI key missing"
try:
output = provider.generate(llm_input)
except AuthenticationError:
rotate_key()
raise Defensive patterns
Strategy: validation
Validate before calling
import os
from llm.providers.openai import OpenAIProvider
def openai_ready() -> bool:
return bool(os.environ.get("OPENAI_API_KEY")) and OpenAIProvider().validate_config() Type guard
from llm.core.interface import AuthenticationError
def is_auth_error(exc: BaseException) -> bool:
return isinstance(exc, AuthenticationError) Try / catch
from llm.core.interface import AuthenticationError
try:
output = provider.generate(llm_input)
except AuthenticationError as e:
logger.error("OpenAI auth failed — rotate key: %s", e)
raise Prevention
- Call provider.validate_config() at startup before any generate() call.
- Inject keys via a secret manager, not hard-coded env files.
- Rotate keys on a schedule and fail fast on 401.
- If using a proxy base_url, document which credential it expects.
When it happens
Trigger: OPENAI_API_KEY unset or empty (client still constructs due to _enforce_credentials=False); key revoked or rotated; key lacks permission for the requested model; base_url points at a proxy that requires its own auth.
Common situations: Missing .env / env var; CI secret not injected; key rotated but old value cached; using an org key for a model in a different project; Azure/proxy base_url with a credential meant for another backend.
Related errors
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/b73675af86d10ca2.
Report an issue: GitHub.