Skip to content

LLM CONNECTION FAILED — duplicate api_key keyword argument when LLM_API_BASE is set to a custom endpoint #1095

Description

@PyLuke73

Bug: LLM CONNECTION FAILED — duplicate api_key keyword argument when LLM_API_BASE is set to a custom endpoint

Environment

  • Strix version: v1.5.3 (standalone binary install via curl -sSL https://strix.ai/install | bash)
  • OS: Debian 13 (trixie), x86_64
  • Sandbox image: ghcr.io/usestrix/strix-sandbox:1.3.0

Summary

Strix fails immediately on its very first LLM call — before any scanning starts — whenever LLM_API_BASE is pointed at a custom (self-hosted / gateway) endpoint instead of a real Anthropic/OpenAI endpoint. This breaks any setup that routes Strix through a local LLM gateway.

Steps to reproduce

  1. Stand up (or point at) any OpenAI/Anthropic-compatible HTTP gateway on your LAN — in our case a self-hosted router forwarding to real provider APIs. The gateway itself is not the point of failure; any custom LLM_API_BASE reproduces this.

  2. Write ~/.strix/cli-config.json:

    {
      "env": {
        "STRIX_LLM": "anthropic/deepseek-main",
        "LLM_API_KEY": "placeholder",
        "LLM_API_BASE": "http://192.168.1.18:8081"
      }
    }
  3. Run:

    strix -n -m quick --max-turns 1 -t "http://example-target"

Expected behavior

Strix connects to the configured model at LLM_API_BASE and proceeds with the scan.

Actual behavior

Fails immediately, before any target interaction:

╭─ STRIX ──────────────────────────────────────────────────────────────────────╮
│                                                                              │
│  LLM CONNECTION FAILED                                                       │
│                                                                              │
│  Could not establish connection to the language model.                       │
│  Please check your configuration and try again.                              │
│                                                                              │
│  Error: litellm.main.acompletion() got multiple values for keyword argument  │
│  'api_key'                                                                   │
│                                                                              │
╰──────────────────────────────────────────────────────────────────────────────╯

A second data point: same failure class, different provider prefix

Switching STRIX_LLM from anthropic/deepseek-main to openai/deepseek-main (and LLM_API_BASE to the gateway's OpenAI-compatible path, .../v1) does not avoid the bug — it fails the same way through a different code path:

Error: AsyncCompletions.create() got an unexpected keyword argument 'api_key'

Since the failure reproduces across both the anthropic/ and openai/ litellm provider prefixes, it looks specific to the "custom LLM_API_BASE is set" code path rather than to one particular provider integration.

Suspected root cause (traced across both repos)

  1. strix/config/models.py:565 — when llm.api_base is set, _configure_litellm_default("api_key", llm.api_key) does setattr(litellm, "api_key", value), i.e. sets a process-wide global default on the litellm module itself.
  2. Strix never passes an explicit api_key when the model resolves to LitellmModel (only the openai/-native path at models.py:712 sets one, via a plain AsyncOpenAI client — a different route). So openai-agents' LitellmModel.api_key stays None (constructor default, openai-agents-python's src/agents/extensions/models/litellm_model.py:150,155).
  3. That same file still forwards it explicitly on every call: src/agents/extensions/models/litellm_model.py:597-617 calls litellm.acompletion(..., api_key=self.api_key, base_url=self.base_url, **extra_kwargs) (the explicit api_key=None at line 614).

So by the time litellm.acompletion() is entered, it has both a request-scoped api_key=None keyword argument and the module-level litellm.api_key global that Strix set in step 1. Somewhere inside litellm's own acompletion()/completion() dispatch (litellm/main.py, matching the traceback frame File "litellm/main.py", line 660, in acompletion), the global default appears to get folded back into the same kwargs path that already carries the explicit (if None) api_key, producing the literal Python TypeError: got multiple values for keyword argument 'api_key'. I didn't trace further into litellm's own multi-thousand-line dispatch code, but steps 1-3 above are enough to reproduce and pin down: the moment _configure_litellm_default("api_key", ...) runs and the resolved model goes through LitellmModel (i.e. any non-openai/-native prefix with a custom api_base), both an instance-level and a module-level api_key are in flight for the same call.

Impact

Any deployment that routes Strix through a self-hosted or gateway LLM_API_BASE (rather than talking to a real Anthropic/OpenAI/etc. endpoint directly) can no longer connect to any model at all, on the very first call.

Additional notes

  • Confirmed on both the current latest release (v1.5.3, 2026-08-10) and the older v1.4.1 (2026-07-27) — identical error message on both, installed via VERSION=1.4.1 curl -sSL https://strix.ai/install | bash. So this isn't a recent regression; it's been present for at least three weeks.
  • Happy to provide additional logs, a minimal agents/litellm repro script, or test a patch if useful.

This report was written with the help of Claude Code (Claude Sonnet 5).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions