affaan-m/ECC · error · AuthenticationError
{msg}
Error message
{msg} What it means
The generate() method of the Atlas provider wraps any exception from the underlying API call and re-raises it as an AuthenticationError when the exception message contains '401' or 'authentication'. This is the library's translation layer that maps raw provider/HTTP errors into typed LLM exceptions, preserving the original cause via `from e`. If you hit this, the provider rejected your credentials for the completion request.
Solutions
- Verify the Atlas API key is set in the environment and print only its length/prefix to confirm it loaded (never log the full key).
- Test the key independently with curl against the provider's auth endpoint to confirm it is valid and active.
- Regenerate the key in the provider console if it was rotated or revoked, and update the secret store.
- Strip whitespace and confirm the key is bound to the correct organization/project the request targets.
Example fix
// before
provider = AtlasProvider(api_key=os.getenv("ATLAS_API_KEY")) # env var missing -> None
// after
api_key = os.getenv("ATLAS_API_KEY", "").strip()
if not api_key:
raise RuntimeError("ATLAS_API_KEY is not set")
provider = AtlasProvider(api_key=api_key) Defensive patterns
Strategy: try-catch
Validate before calling
api_key = os.getenv("ATLAS_API_KEY", "").strip()
if not api_key:
raise RuntimeError("ATLAS_API_KEY is not configured before calling generate()") Try / catch
try:
out = provider.generate(prompt)
except AuthenticationError as e:
log.error("provider auth rejected: %s", e)
alert_or_reconfigure_credentials() Prevention
- Fail fast at startup: validate the API key exists and is non-empty before constructing the provider.
- Keep keys in a secret manager and inject them per environment; never hardcode.
- Re-verify keys after rotations and in CI by making a cheap authenticated probe call.
When it happens
Trigger: Calling provider.generate() (or any wrapper invoking it) while the upstream API responds 401 Unauthorized, or the underlying SDK error message contains the substring '401' or 'authentication' — e.g. an invalid, revoked, or missing API key used for the chat-completion request.
Common situations: ATLAS_API_KEY not set or set to a placeholder in the environment; key rotated or revoked server-side; key copied with stray whitespace/newline; using a key for the wrong org/project or an expired trial; sandbox CI environment lacking the secret.
Related errors
- msg
- {msg}
- AuthenticationError(msg, provider=ProviderType.OPENAI) from…
- FAL_KEY is not set. Get a key at…
- GitHub GraphQL request failed
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/d3a736a301ef405e.
Report an issue: GitHub.
Appendix: source
Thrown at src/llm/providers/atlas.py:133
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=self.provider_type) from e
if "429" in msg or "rate_limit" in msg.lower():
raise RateLimitError(msg, provider=self.provider_type) from e
if "context" in msg.lower() and "length" in msg.lower():
raise ContextLengthError(msg, provider=self.provider_type) from e
raise
def list_models(self) -> list[ModelInfo]:
return self._models.copy()
def validate_config(self) -> bool:
return bool(self.api_key)
def get_default_model(self) -> str:
return self.default_model
View on GitHub (pinned to 8321021c54)