Skip to content

Credential pool key mix-up when multiple custom providers share the same base_url #19083

@imkenf

Description

@imkenf

Bug: Credential pool key mix-up when multiple custom providers share the same base_url

Summary

When multiple custom_providers are configured with the same base_url but different api_key values, Hermes incorrectly resolves the credential pool, causing API requests to use the wrong API key.

Root Cause

File: agent/credential_pool.py
Function: get_custom_provider_pool_key(base_url: str)

def get_custom_provider_pool_key(base_url: str) -> str:
    for provider in _iter_custom_providers():
        if provider.get("base_url") == base_url:
            return f"custom:{provider['name']}"  # ← Always returns FIRST match
    return ""

This function only matches by base_url, ignoring which provider name is actually being requested. When two providers share the same base_url, it always returns the pool key for the first one in iteration order.

Reproduction

Config

custom_providers:
  - name: provider-a
    base_url: http://<gateway-host>:<port>
    api_key: sk-xxx...aaa
    model: model-a

  - name: provider-b
    base_url: http://<gateway-host>:<port>   # Same base_url
    api_key: sk-xxx...bbb                    # Different key
    model: model-b
hermes config set model.provider provider-b
hermes chat -q "Hello"

Result

  • Expected: Uses provider-b's key (sk-xxx...bbb)
  • Actual: Uses provider-a's key (sk-xxx...aaa) because get_custom_provider_pool_key() returns custom:provider-a

Evidence

agent.model_metadata - Failed to fetch model metadata: 401 Unauthorized

Direct API test with correct key:

requests.get("http://<gateway-host>:<port>/v1/models",
             headers={"Authorization": "Bearer sk-xxx...bbb"})
# => 200 OK

Call Chain

resolve_runtime_provider()
  └─ _try_resolve_from_custom_pool(base_url, ...)
       └─ get_custom_provider_pool_key(base_url)  # ← Bug here
            └─ Returns "custom:provider-a" (first match)
                 └─ load_pool("custom:provider-a")  # Wrong pool!

Environment

  • Hermes v0.12.0 (upstream 5d3be89)
  • Python 3.11, OpenAI SDK 2.32.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — major feature broken, no workaroundarea/configConfig system, migrations, profilescomp/agentCore agent loop, run_agent.py, prompt buildertype/bugSomething isn't working

    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