hermes - 💡(How to fix) Fix [Feature]: `hermes setup` should allow replacing an existing API key instead of silently skipping the prompt [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#16394Fetched 2026-04-28 06:53:39
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Participants
Timeline (top)
labeled ×4referenced ×1

Error Message

  1. Error message says: 💡 Is the key valid? Run: hermes setup. The only recovery today is to exit, manually nano ~/.hermes/.env, delete the DEEPSEEK_API_KEY= line, and re-run hermes setup. That's unfriendly for new users and directly contradicts the error message that tells them to run hermes setup.
  • The current flow sends users into a manual-file-edit dead end that the error message itself cannot recover from.
  1. Document the workaround (edit .env manually) more prominently in the 401 error message. Solves discoverability but doesn't solve the UX issue; it still requires users to hand-edit a dotfile. The proposed "keep / replace / clear" menu is the smallest change that restores the promise implied by the wizard's own error message ("run hermes setup").

Fix Action

Fix / Workaround

  1. Add a CLI flag like hermes setup --reset-keys that nukes all stored credentials before running the wizard. Works, but requires the user to know the flag exists and is a much bigger hammer than "let me change one key."
  2. Document the workaround (edit .env manually) more prominently in the 401 error message. Solves discoverability but doesn't solve the UX issue; it still requires users to hand-edit a dotfile.
  3. Auto-validate the key on startup and invalidate if 401 — opinionated, could fail on transient network errors, probably not desirable.

Code Example

DeepSeek API key: sk-c7be8...
---

# 1. Put a malformed value in the key
echo "DEEPSEEK_API_KEY=sk-this-is-not-a-real-key-but-a-long-string-of-junk" >> ~/.hermes/.env

# 2. Run setup
hermes setup
# Wizard prints "DeepSeek API key: sk-this-... ✓" and moves on.
# There is no prompt to replace it.

---

else:
    print(f"  {pconfig.name} API key: {existing_key[:8]}... ✓")
    print()

---

else:
    print(f"  {pconfig.name} API key: {existing_key[:8]}... (stored, not validated)")
    action = prompt_choice(
        "What would you like to do?",
        [
            "Keep current key",
            "Replace with a new key",
            "Remove key",
        ],
        default=0,
    )
    if action == 1:
        new_key = getpass.getpass(f"{key_env}: ").strip()
        if new_key:
            save_env_value(key_env, new_key)
            existing_key = new_key
            print("API key replaced.")
    elif action == 2:
        save_env_value(key_env, "")
        existing_key = ""
        print("API key removed.")
    print()
RAW_BUFFERClick to expand / collapse

Problem or Use Case

When running hermes setup (or hermes model), the inference-provider configuration step silently skips the API-key prompt if any value is already present in ~/.hermes/.env — regardless of whether that value is a valid key, a malformed key, or even completely unrelated text. The only indication is a green checkmark:

  DeepSeek API key: sk-c7be8... ✓

The only means "a non-empty string exists for DEEPSEEK_API_KEY". It does not validate:

  • Length/format of the key (I accidentally pasted 343 characters of junk starting with sk-, and the wizard treated it as configured).
  • Whether the key actually works against the provider's endpoint.

Impact for the user: if you ever paste the wrong thing into an API-key prompt (extra whitespace, wrong provider's key, a JWT, a multi-line paste that got concatenated, etc.), you get stuck in a loop:

  1. hermes → chat fails with HTTP 401: Authentication Fails, Your api key: ****xxxx is invalid.
  2. Error message says: 💡 Is the key valid? Run: hermes setup.
  3. You run hermes setup → wizard shows API key: sk-xxx... ✓ and jumps straight past the key entry, going to the Base URL prompt.
  4. No way inside the wizard to say "the stored key is bad, let me enter a new one."

The only recovery today is to exit, manually nano ~/.hermes/.env, delete the DEEPSEEK_API_KEY= line, and re-run hermes setup. That's unfriendly for new users and directly contradicts the error message that tells them to run hermes setup.

This affects every provider configured via the same code path — the API key: xxxxx... ✓ / else-branch pattern appears in hermes_cli/main.py at lines 3811, 3930, and 4324 (and a similar "already configured" short-circuit exists throughout hermes_cli/setup.py for Modal, Daytona, Telegram, Discord, Slack, Matrix, Mattermost, BlueBubbles, Webhooks, etc.).

Reproduction

# 1. Put a malformed value in the key
echo "DEEPSEEK_API_KEY=sk-this-is-not-a-real-key-but-a-long-string-of-junk" >> ~/.hermes/.env

# 2. Run setup
hermes setup
# Wizard prints "DeepSeek API key: sk-this-... ✓" and moves on.
# There is no prompt to replace it.

Environment

  • Hermes Agent 0.11.0 (commit 6c873718)
  • WSL2 Ubuntu 24.04, Python 3.11
  • Provider: DeepSeek (reproducible on any provider that stores its key directly in .env)

Proposed Solution

Change the else branch that currently just prints the line into an interactive "keep / replace / clear" menu. Concretely, in hermes_cli/main.py around lines 3810, 3929, 4323, replace:

else:
    print(f"  {pconfig.name} API key: {existing_key[:8]}... ✓")
    print()

with something like:

else:
    print(f"  {pconfig.name} API key: {existing_key[:8]}... (stored, not validated)")
    action = prompt_choice(
        "What would you like to do?",
        [
            "Keep current key",
            "Replace with a new key",
            "Remove key",
        ],
        default=0,
    )
    if action == 1:
        new_key = getpass.getpass(f"{key_env}: ").strip()
        if new_key:
            save_env_value(key_env, new_key)
            existing_key = new_key
            print("API key replaced.")
    elif action == 2:
        save_env_value(key_env, "")
        existing_key = ""
        print("API key removed.")
    print()

Optionally, pair this with a lightweight validity probe — make a single unauthenticated-friendly request (GET /models for OpenAI-compatible endpoints, or a 1-token ping) and show ✓ verified vs ⚠ unverified — server returned 401 next to the key. That would turn the current checkmark from a misleading claim into a meaningful one.

Why this is worth doing

  • The current flow sends users into a manual-file-edit dead end that the error message itself cannot recover from.
  • It's a small, self-contained change (one helper, three call sites in main.py, plus a similar pattern across setup.py for other credentials).
  • It also sets the pattern right for any future provider added to PROVIDER_REGISTRY — the else-branch boilerplate gets copy-pasted each time.

Alternatives Considered

  1. Add a CLI flag like hermes setup --reset-keys that nukes all stored credentials before running the wizard. Works, but requires the user to know the flag exists and is a much bigger hammer than "let me change one key."
  2. Document the workaround (edit .env manually) more prominently in the 401 error message. Solves discoverability but doesn't solve the UX issue; it still requires users to hand-edit a dotfile.
  3. Auto-validate the key on startup and invalidate if 401 — opinionated, could fail on transient network errors, probably not desirable.

The proposed "keep / replace / clear" menu is the smallest change that restores the promise implied by the wizard's own error message ("run hermes setup").


Feature Type

CLI improvement

Scope

Small (single file, < 50 lines)

extent analysis

TL;DR

Implement a "keep / replace / clear" menu for API keys in the hermes setup wizard to allow users to manage their keys effectively.

Guidance

  • Modify the else branch in hermes_cli/main.py around lines 3810, 3929, 4323 to include an interactive menu for managing API keys.
  • Use a prompt_choice function to present users with options to keep, replace, or remove their current API key.
  • Consider adding a lightweight validity probe to verify the API key and display a corresponding status message.
  • Update the setup.py file to reflect the same changes for other credentials.

Example

else:
    print(f"  {pconfig.name} API key: {existing_key[:8]}... (stored, not validated)")
    action = prompt_choice(
        "What would you like to do?",
        [
            "Keep current key",
            "Replace with a new key",
            "Remove key",
        ],
        default=0,
    )
    if action == 1:
        new_key = getpass.getpass(f"{key_env}: ").strip()
        if new_key:
            save_env_value(key_env, new_key)
            existing_key = new_key
            print("API key replaced.")
    elif action == 2:
        save_env_value(key_env, "")
        existing_key = ""
        print("API key removed.")
    print()

Notes

  • The proposed solution aims to address the issue of silently skipping the API-key prompt when a value is already present in ~/.hermes/.env.
  • The changes should be applied to all providers that store their keys directly in .env.
  • The validity probe is optional but can provide an additional layer of verification for the API key.

Recommendation

Apply the proposed workaround by implementing the "keep / replace / clear" menu for API keys in the hermes setup wizard

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 - 💡(How to fix) Fix [Feature]: `hermes setup` should allow replacing an existing API key instead of silently skipping the prompt [1 participants]