hermes - ✅(Solved) Fix TUI: /new after /model switch to custom provider model fails with 'no API key' when model name exists in native provider catalog [2 pull requests, 1 participants]

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…
GitHub stats
NousResearch/hermes-agent#16857Fetched 2026-04-29 06:38:27
View on GitHub
Comments
0
Participants
1
Timeline
10
Reactions
0
Participants
Timeline (top)
labeled ×5cross-referenced ×2referenced ×2closed ×1

Error Message

error: agent init failed: Provider 'deepseek' is set in config.yaml but no API key was found. Set the DEEPSEEK_API_KEY environment variable, or switch to a different provider with hermes model.

Root Cause

In tui_gateway/server.py, _resolve_startup_runtime() (line ~628):

  1. /model correctly sets HERMES_MODEL=deepseek-v4-pro and HERMES_INFERENCE_PROVIDER=custom:xuanji in env vars
  2. On /new, _resolve_startup_runtime() detects HERMES_MODEL is set (line 634-637)
  3. It reads config.model.provider (custom:xuanji) as current_provider (line 644-652)
  4. It calls detect_static_provider_for_model("deepseek-v4-pro", "custom:xuanji") (line 654)
  5. Since custom:xuanji has no static catalog, _model_in_provider_catalog() returns False
  6. The function iterates all native provider catalogs and matches deepseek-v4-pro to the native deepseek provider
  7. Returns ("deepseek", "deepseek-v4-pro"), overriding the correct custom:xuanji provider
  8. resolve_runtime_provider then fails because DEEPSEEK_API_KEY is not set

Note: This bug is masked for models like claude-opus-4-7 if ANTHROPIC_API_KEY happens to be set — the wrong provider is used but authentication succeeds by coincidence.

Fix Action

Fixed

PR fix notes

PR #16873: fix(gateway): honour HERMES_INFERENCE_PROVIDER in _resolve_startup_runtime (#16857)

Description (problem / solution / changelog)

Summary

Fixes #16857 — /new after /model switch to a custom provider model fails with "no API key" when the model name also exists in a native provider catalog.

Root Cause

In _resolve_startup_runtime(), HERMES_INFERENCE_PROVIDER (set by /model) was passed as a hint to detect_static_provider_for_model(), but custom providers have no static catalog. The function fell through to matching native catalogs by model name, overriding the explicit custom provider choice with the coincidentally-matching native provider.

Example: /model deepseek-v4-pro via custom:xuanji/newdetect_static_provider_for_model matches native deepseek catalog → tries to use DEEPSEEK_API_KEY → 401.

Fix

Check HERMES_INFERENCE_PROVIDER immediately after HERMES_TUI_PROVIDER and return early when set. This env var is written by /model and represents the user's explicit provider choice — static catalog detection must not override it.

Also removes the now-redundant HERMES_INFERENCE_PROVIDER read from the current_provider fallback chain (line 651 of the original), since the early return means it can never be reached.

Changes

  • tui_gateway/server.py: Early-return on HERMES_INFERENCE_PROVIDER before static detection
  • tests/test_tui_gateway_server.py: Updated existing test + added 2 new tests

Testing

python3 -m pytest tests/test_tui_gateway_server.py -k "startup_runtime" -x -q -o "addopts="
# 6 passed

Test coverage:

TestVerifies
test_startup_runtime_honours_inference_provider_envCustom provider is returned directly; static detection is NOT called
test_startup_runtime_inference_provider_does_not_override_tui_providerHERMES_TUI_PROVIDER still takes precedence
Existing testsNo regression in alias resolution, static detection, TUI provider

How to verify manually

  1. Configure a custom provider with a model name that overlaps a native catalog
  2. /model <overlapping-model-name> → should switch to custom provider
  3. /new → should start new session with the custom provider, not the native one

Changed files

  • tests/test_tui_gateway_server.py (modified, +23/-5)
  • tui_gateway/server.py (modified, +8/-1)

PR #16897: fix(tui): /model writes HERMES_TUI_PROVIDER unconditionally (#16857)

Description (problem / solution / changelog)

Summary

/new after /model <custom-provider>:<model> now honours the user's explicit provider choice instead of silently reverting to a native provider that coincidentally has the model in its static catalog (e.g. deepseek-v4-pro → native deepseek → 401).

Root cause

In _apply_model_switch (tui_gateway/server.py:850-853), /model set HERMES_INFERENCE_PROVIDER unconditionally but mirrored to HERMES_TUI_PROVIDER only if it was already set. Sessions launched without --provider never have HERMES_TUI_PROVIDER set, so on /new, _resolve_startup_runtime() skipped the explicit-provider early return (which keys off HERMES_TUI_PROVIDER) and fell through to detect_static_provider_for_model(), which matched the model name against native catalogs.

Why fix at the /model writeback site, not _resolve_startup_runtime

@Bartok9's original PR #16873 early-returned HERMES_INFERENCE_PROVIDER in _resolve_startup_runtime. That works for this bug but partially reverts #15755 (commit 57b43fd), which deliberately removed that early return because HERMES_INFERENCE_PROVIDER can be ambient (shell-inherited, .env, persisted from prior processes) and ambient values shouldn't short-circuit resolution.

Brooklyn's invariant from #15755:

  • HERMES_TUI_PROVIDER = explicit-this-process (user chose it via --provider or /model)
  • HERMES_INFERENCE_PROVIDER = ambient (may be stale)

The real bug was that /model wasn't writing to the canonical "explicit" carrier. Fixing at the writeback site preserves both invariants simultaneously.

Changes

  • tui_gateway/server.py: /model now sets HERMES_TUI_PROVIDER = target_provider unconditionally alongside HERMES_INFERENCE_PROVIDER.
  • tests/test_tui_gateway_server.py: regression test test_config_set_model_syncs_tui_provider_unconditionally covers the #16857 scenario (no pre-set HERMES_TUI_PROVIDER, custom provider selection).

Validation

BeforeAfter
Targeted tests (8)N/Aall pass (syncs_tui_provider, syncs_inference_provider, startup_runtime)
E2E /model custom:xuanji/newresolves to native deepseek → 401resolves to custom:xuanji
E2E ambient HERMES_INFERENCE_PROVIDER alonefalls through to static detectionfalls through to static detection (unchanged; #15755 invariant preserved)

Credit

Bug report, diagnosis, and initial fix: @Bartok9 in #16857 and #16873. This salvage PR reapplies the fix at the writeback site to avoid reverting #15755.

Closes #16857 Supersedes #16873

Changed files

  • tests/test_tui_gateway_server.py (modified, +55/-0)
  • tui_gateway/server.py (modified, +11/-6)

Code Example

error: agent init failed: Provider 'deepseek' is set in config.yaml but no API key was found.
Set the DEEPSEEK_API_KEY environment variable, or switch to a different provider with `hermes model`.

---

# If /model set HERMES_INFERENCE_PROVIDER, honour it directly
inference_provider = os.environ.get("HERMES_INFERENCE_PROVIDER", "").strip()
if inference_provider:
    return model, inference_provider
RAW_BUFFERClick to expand / collapse

Bug Description

When using /model to switch to a model served via a custom provider (e.g. custom:xuanji), and the model name also exists in a native provider's static catalog (e.g. deepseek-v4-pro exists in the native deepseek provider catalog), running /new fails with:

error: agent init failed: Provider 'deepseek' is set in config.yaml but no API key was found.
Set the DEEPSEEK_API_KEY environment variable, or switch to a different provider with `hermes model`.

Steps to Reproduce

  1. Configure a custom provider (e.g. custom:xuanji) with models like deepseek-v4-pro
  2. In TUI, run /model deepseek-v4-pro — switches successfully to custom:xuanji
  3. Run /new — fails with the error above

Root Cause

In tui_gateway/server.py, _resolve_startup_runtime() (line ~628):

  1. /model correctly sets HERMES_MODEL=deepseek-v4-pro and HERMES_INFERENCE_PROVIDER=custom:xuanji in env vars
  2. On /new, _resolve_startup_runtime() detects HERMES_MODEL is set (line 634-637)
  3. It reads config.model.provider (custom:xuanji) as current_provider (line 644-652)
  4. It calls detect_static_provider_for_model("deepseek-v4-pro", "custom:xuanji") (line 654)
  5. Since custom:xuanji has no static catalog, _model_in_provider_catalog() returns False
  6. The function iterates all native provider catalogs and matches deepseek-v4-pro to the native deepseek provider
  7. Returns ("deepseek", "deepseek-v4-pro"), overriding the correct custom:xuanji provider
  8. resolve_runtime_provider then fails because DEEPSEEK_API_KEY is not set

Note: This bug is masked for models like claude-opus-4-7 if ANTHROPIC_API_KEY happens to be set — the wrong provider is used but authentication succeeds by coincidence.

Expected Behavior

/new should respect the HERMES_INFERENCE_PROVIDER env var set by /model, since it represents the user's explicit provider choice.

Suggested Fix

In _resolve_startup_runtime(), check HERMES_INFERENCE_PROVIDER before falling through to detect_static_provider_for_model():

# If /model set HERMES_INFERENCE_PROVIDER, honour it directly
inference_provider = os.environ.get("HERMES_INFERENCE_PROVIDER", "").strip()
if inference_provider:
    return model, inference_provider

This should be inserted after the HERMES_TUI_PROVIDER check (line 630-632) and before the static detection logic.

Environment

  • Hermes Agent TUI mode
  • Custom provider with models that share names with native provider catalogs

extent analysis

TL;DR

To fix the issue, insert a check for the HERMES_INFERENCE_PROVIDER environment variable in the _resolve_startup_runtime() function to honor the user's explicit provider choice.

Guidance

  • Verify that the HERMES_INFERENCE_PROVIDER environment variable is set correctly after running /model by checking the environment variables in your setup.
  • Insert the suggested fix code after the HERMES_TUI_PROVIDER check in _resolve_startup_runtime() to prioritize the user-set provider.
  • Test the fix by running /new after switching to a model with a custom provider to ensure it no longer fails due to the wrong provider being detected.
  • Be aware that this fix assumes the HERMES_INFERENCE_PROVIDER variable is correctly set by the /model command and that the custom provider is properly configured.

Example

# If /model set HERMES_INFERENCE_PROVIDER, honour it directly
inference_provider = os.environ.get("HERMES_INFERENCE_PROVIDER", "").strip()
if inference_provider:
    return model, inference_provider

Notes

This fix is specific to the described scenario where a custom provider's model name conflicts with a native provider's catalog. It does not address potential issues with other parts of the system.

Recommendation

Apply the suggested workaround by inserting the HERMES_INFERENCE_PROVIDER check in _resolve_startup_runtime() to ensure the correct provider is used when running /new after switching models with /model.

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

hermes - ✅(Solved) Fix TUI: /new after /model switch to custom provider model fails with 'no API key' when model name exists in native provider catalog [2 pull requests, 1 participants]