xai-org/x-algorithm · critical · ValueError

API key is required: set EapiModelConfig.api_key or the XAI_

Error message

API key is required: set EapiModelConfig.api_key or the XAI_API_KEY environment variable.

What it means

EapiSampler requires an API key before it can construct its xAI client. In __init__, it falls back from EapiModelConfig.api_key to the XAI_API_KEY environment variable and raises ValueError if both are empty/None. This is a fail-fast guard so the sampler never gets constructed with unusable credentials.

Source

Thrown at grox/libs/grok_sampler/eapi_sampler.py:68

class EapiSampler:
    _cached_clients: dict[tuple[int, str, str], AsyncClient] = {}

    def __init__(self, eapi_config: EapiModelConfig):
        self.model: str = eapi_config.model
        self.temperature: float = eapi_config.temperature
        self.timeout: int = eapi_config.timeout
        self.max_tokens = eapi_config.max_resp_len
        self.api_key = eapi_config.api_key
        self.api_host = eapi_config.api_host
        self.log_reasoning_trace: bool = eapi_config.log_reasoning_trace
        self.enable_search: bool = eapi_config.enable_search
        self.reasoning_effort: str | None = eapi_config.reasoning_effort

        api_key = self.api_key or os.getenv("XAI_API_KEY")

        if not api_key:
            raise ValueError(
                "API key is required: set EapiModelConfig.api_key or the XAI_API_KEY environment variable."
            )

        self.client_kwargs = {
            "api_key": api_key,
            "timeout": self.timeout,
            "channel_options": [("grpc.enable_retries", 0)],
        }

        if self.api_host:
            self.client_kwargs["api_host"] = self.api_host

    def _get_client(self) -> AsyncClient:
        loop_id = get_loop_id()
        key = (loop_id, self.model, self.api_host)
        if key in self._cached_clients:
            client = self._cached_clients[key]
            return client

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Set the XAI_API_KEY environment variable in the runtime environment (export XAI_API_KEY=... or inject via your deployment secrets).
  2. Alternatively pass api_key explicitly: EapiModelConfig(api_key='...', ...) so the code does not depend on env.
  3. Check for typos/whitespace: an empty-string or whitespace-only value still fails; verify with python -c "import os;print(repr(os.getenv('XAI_API_KEY')))").
  4. If using .env files, ensure the loader (dotenv/settings) runs before EapiSampler is created.

Example fix

# before
sampler = EapiSampler(EapiModelConfig())  # ValueError: API key is required

# after
sampler = EapiSampler(EapiModelConfig(api_key=os.environ['XAI_API_KEY']))
Defensive patterns

Strategy: validation

Validate before calling

api_key = cfg.api_key or os.getenv('XAI_API_KEY')
if not api_key:
    raise SystemExit('XAI_API_KEY not set; refusing to start')

Try / catch

try:
    sampler = EapiSampler(cfg)
except ValueError as e:
    if 'API key is required' in str(e):
        logger.error('Missing xAI credentials; check secret injection')
    raise

Prevention

When it happens

Trigger: Instantiating EapiSampler (or an orchestrator that builds it) with an EapiModelConfig where api_key is None/empty AND os.getenv('XAI_API_KEY') is also unset or empty in the process environment.

Common situations: Deploying to a new environment (container, CI, k8s pod) where XAI_API_KEY was never injected; passing api_key='' instead of a real key; running locally with the var only set in a different shell or virtualenv activation; .env file not loaded before sampler construction.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/f3efe1b2355afc62. Report an issue: GitHub.