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

  1. 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).
  2. Test the key independently with curl against the provider's auth endpoint to confirm it is valid and active.
  3. Regenerate the key in the provider console if it was rotated or revoked, and update the secret store.
  4. 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

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


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)