hermes - 💡(How to fix) Fix [Bug]: auxiliary "use as" in dashboard copies base_url but omits api_key, causing 401 on authenticated custom endpoints

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

When using the web dashboard (Config → auxiliary section) and clicking "use as" to apply the current model endpoint to an auxiliary task (e.g. title_generation), the base_url is copied but api_key is left empty. This causes HTTP 401 errors at runtime on any custom endpoint that requires authentication.

Error Message

Operating System

Ubuntu 20.04.6 LTS

Python Version

No response

Hermes Version

No response

Additional Logs / Traceback (optional)

Root Cause

Two related issues:

Fix Action

Fix / Workaround

Workaround

Code Example

model:
provider: custom
base_url: "http://localhost:8081/v1"
api_key: "83a7ee97-xxxx"   # set
default: gemma4-31b

auxiliary:
title_generation:
base_url: "http://localhost:8081/v1"   # copied by "use as"
api_key: ""                             # NOT copied → 401

2. resolve_provider_client falls back to "no-key-required" instead of model.api_key

In agent/auxiliary_client.py (~line 2183), when explicit_base_url is set:

                                                                     custom_key = (
                                                                       (explicit_api_key or "").strip()
                                                                       or os.getenv("OPENAI_API_KEY", "").strip()
                                                                       or "no-key-required"   # silently used when api_key is empty
                                                                     )

When auxiliary.<task>.api_key is empty and OPENAI_API_KEY env var is not set, the request goes out with Authorization: Bearer no-key-required → HTTP 401. The main model config model.api_key is never consulted, even when the base URL is the same endpoint.


Workaround

Manually set api_key under the auxiliary task in config.yaml:

auxiliary:
title_generation:
provider: custom
model: gemma4-31b
base_url: http://localhost:8081/v1
api_key: your-api-key

Environment

- Custom vLLM endpoint requiring Bearer token auth
- Hermes gateway via Docker, Slack platform

### Steps to Reproduce

1. Configure a custom endpoint with auth (model.provider: custom, model.api_key: <key>)
2. Open dashboard → Config → auxiliary → title_generation
3. Click "use as"
4. Send a message via gateway
5. Observe:Auxiliary title generation failed: HTTP 401: {"error": "Unauthorized"}


### Expected Behavior

- Dashboard "use as" should propagate api_key alongside base_url
- resolve_provider_client should fall back to model.api_key when auxiliary.<task>.api_key is empty and the host matches model.base_url

### Actual Behavior

After clicking "use as" on the `title_generation` auxiliary task, `config.yaml` is saved with `base_url` populated but `api_key` empty. On the next agent session, every title generation request is sent to the custom endpoint with `Authorization: Bearer no-key-required`, which the server rejects:

WARNING agent.auxiliary_client: resolve_provider_client: custom/main requested but no endpoint credentials found
WARNING agent.title_generator: Title generation failed: Error code: 401 - {'error': 'Unauthorized'}
Auxiliary title generation failed: HTTP 401: Error code: 401 - {'error': 'Unauthorized'}

Sessions are created without titles (NULL in the session store) and the warning is surfaced to the user on every message.

### Affected Component

Setup / Installation

### Messaging Platform (if gateway-related)

_No response_

### Debug Report

---

### Operating System

Ubuntu 20.04.6 LTS

### Python Version

_No response_

### Hermes Version

_No response_

### Additional Logs / Traceback (optional)
RAW_BUFFERClick to expand / collapse

Bug Description

Summary

When using the web dashboard (Config → auxiliary section) and clicking "use as" to apply the current model endpoint to an auxiliary task (e.g. title_generation), the base_url is copied but api_key is left empty. This causes HTTP 401 errors at runtime on any custom endpoint that requires authentication.

Root Cause

Two related issues:

1. Dashboard "use as" does not copy api_key

Only base_url (and model) are written — api_key from model.api_key is not propagated:

model:
provider: custom
base_url: "http://localhost:8081/v1"
api_key: "83a7ee97-xxxx"   # set
default: gemma4-31b

auxiliary:
title_generation:
base_url: "http://localhost:8081/v1"   # copied by "use as"
api_key: ""                             # NOT copied → 401

2. resolve_provider_client falls back to "no-key-required" instead of model.api_key

In agent/auxiliary_client.py (~line 2183), when explicit_base_url is set:

                                                                     custom_key = (
                                                                       (explicit_api_key or "").strip()
                                                                       or os.getenv("OPENAI_API_KEY", "").strip()
                                                                       or "no-key-required"   # silently used when api_key is empty
                                                                     )

When auxiliary.<task>.api_key is empty and OPENAI_API_KEY env var is not set, the request goes out with Authorization: Bearer no-key-required → HTTP 401. The main model config model.api_key is never consulted, even when the base URL is the same endpoint.


Workaround

Manually set api_key under the auxiliary task in config.yaml:

auxiliary:
title_generation:
provider: custom
model: gemma4-31b
base_url: http://localhost:8081/v1
api_key: your-api-key

Environment

- Custom vLLM endpoint requiring Bearer token auth
- Hermes gateway via Docker, Slack platform

### Steps to Reproduce

1. Configure a custom endpoint with auth (model.provider: custom, model.api_key: <key>)
2. Open dashboard → Config → auxiliary → title_generation
3. Click "use as"
4. Send a message via gateway
5. Observe: ⚠ Auxiliary title generation failed: HTTP 401: {"error": "Unauthorized"}


### Expected Behavior

- Dashboard "use as" should propagate api_key alongside base_url
- resolve_provider_client should fall back to model.api_key when auxiliary.<task>.api_key is empty and the host matches model.base_url

### Actual Behavior

After clicking "use as" on the `title_generation` auxiliary task, `config.yaml` is saved with `base_url` populated but `api_key` empty. On the next agent session, every title generation request is sent to the custom endpoint with `Authorization: Bearer no-key-required`, which the server rejects:

WARNING agent.auxiliary_client: resolve_provider_client: custom/main requested but no endpoint credentials found
WARNING agent.title_generator: Title generation failed: Error code: 401 - {'error': 'Unauthorized'}
⚠ Auxiliary title generation failed: HTTP 401: Error code: 401 - {'error': 'Unauthorized'}

Sessions are created without titles (NULL in the session store) and the warning is surfaced to the user on every message.

### Affected Component

Setup / Installation

### Messaging Platform (if gateway-related)

_No response_

### Debug Report

```shell
Gateway logs showing the failure chain:

  WARNING agent.auxiliary_client: resolve_provider_client: custom/main requested but no endpoint credentials found
  WARNING agent.title_generator: Title generation failed: Error code: 401 - {'error': 'Unauthorized'}
  ⚠ Auxiliary title generation failed: HTTP 401: Error code: 401 - {'error': 'Unauthorized'}

  `config.yaml` state after clicking "use as" in the dashboard:

  
  model:
    provider: custom
    base_url: 'http://localhost:8081/v1'
    api_key: '83a7ee97-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
    default: gemma4-31b

  auxiliary:
    title_generation:
      provider: auto
      model: ''
      base_url: 'http://localhost:8081/v1'   # copied
      api_key: ''                             # NOT copied
      timeout: 30
      extra_body: {}

  Relevant code path in agent/auxiliary_client.py:

  # ~line 2183: when explicit_base_url is set but explicit_api_key is empty
  custom_key = (
      (explicit_api_key or "").strip()       # "" — not passed
      or os.getenv("OPENAI_API_KEY", "").strip()  # "" — not set
      or "no-key-required"                   # ← this is used, causes 401
  )

Operating System

Ubuntu 20.04.6 LTS

Python Version

No response

Hermes Version

No response

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

No response

Proposed Fix (optional)

No response

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING