Skip to content

kimi-coding credential pool seeds wrong base_url for sk-kimi- keys, causing 401 on first request #5561

@SeeYangZhi

Description

@SeeYangZhi

Bug Description

The kimi-coding credential pool seeds entries with the wrong base_url for sk-kimi- prefixed keys. This causes the first API call to hit https://api.moonshot.ai/v1 instead of https://api.kimi.com/coding/v1, resulting in an HTTP 401 Invalid Authentication error. The request succeeds on subsequent turns because the non-pool runtime resolver correctly detects the key prefix.

Root Cause

_seed_from_env() in agent/credential_pool.py hardcodes the base URL for API-key providers without running the provider-specific auto-detection logic:

base_url = env_url or pconfig.inference_base_url

For kimi-coding, pconfig.inference_base_url is "https://api.moonshot.ai/v1", so the pool stores that endpoint even when the key is a sk-kimi- prefix key that only works on api.kimi.com/coding/v1.

Meanwhile, resolve_api_key_provider_credentials() in hermes_cli/auth.py does run _resolve_kimi_base_url(), which correctly routes sk-kimi- keys to KIMI_CODE_BASE_URL (https://api.kimi.com/coding/v1).

This mismatch means:

  1. First request uses the pool entry → wrong URL → 401.
  2. Pool marks the credential exhausted.
  3. Next request bypasses the exhausted pool and falls through to the singleton resolver → correct URL → success.

Evidence

~/.hermes/auth.json shows the stale pool entry

{
  "credential_pool": {
    "kimi-coding": [
      {
        "source": "env:KIMI_API_KEY",
        "base_url": "https://api.moonshot.ai/v1",
        "last_status": "exhausted",
        "last_error_code": 401,
        "last_error_message": "Invalid Authentication"
      }
    ]
  }
}

Error log on first attempt

⚠️  API call failed (attempt 1/3): AuthenticationError [HTTP 401]
   🔌 Provider: kimi-coding  Model: kimi-k2.5
   🌐 Endpoint: https://api.moonshot.ai/v1
   📝 Error: HTTP 401: Invalid Authentication

Config has the correct URL

model:
  default: kimi-k2.5
  provider: kimi-coding
  base_url: https://api.kimi.com/coding/v1

Steps to Reproduce

  1. Configure kimi-coding provider with a sk-kimi-* API key.
  2. Ensure KIMI_BASE_URL is not set in the environment.
  3. Start a fresh Hermes session (or delete ~/.hermes/auth.json to clear the pool).
  4. Send any message.
  5. Observe HTTP 401 on the first request, with the endpoint being api.moonshot.ai/v1.
  6. Send a second message — it succeeds because the runtime resolver bypasses the exhausted pool.

Suggested Fix

Make _seed_from_env() use the same Kimi base URL resolution logic as the runtime credential resolver. Specifically, call _resolve_kimi_base_url() when the provider is kimi-coding, or generalize provider-specific URL detection in the credential pool seeder.

# In agent/credential_pool.py:_seed_from_env
base_url = env_url or pconfig.inference_base_url
if provider == "kimi-coding":
    base_url = _resolve_kimi_base_url(token, pconfig.inference_base_url, env_url)

Workarounds

  • Clear the pool: rm ~/.hermes/auth.json
  • Set env override: export KIMI_BASE_URL="https://api.kimi.com/coding/v1"

Affected Code

  • agent/credential_pool.py_seed_from_env()
  • hermes_cli/auth.py_resolve_kimi_base_url() (correct logic already exists here)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions