NousResearch/hermes-agent
Auth API key crash in non-interactive environments
Cluster 10468. Data as of
Nothing open on GitHub. Fix merged in #10599 on 16 Apr 2026. Check it covers your case.
The short answer
0open issues
0open PRs
3items grouped
- Known?
- Yes. 3 related items grouped here, 1 issue already closed.
- Fix event
- A fix was merged to main in PR #10599. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
unresolved. That is separate from the fix event. - Still open
- Nothing open on GitHub.
A bug where hermes auth add api_key crashes when a label prompt is shown in non-interactive environments, along with related CLI quality-of-life fixes. The fix involves silently using a default label when no interactive input is available.
Open issues0
Open PRs0
Fixes on record
-
#10599 fix: three CLI quality-of-life fixes
files:
hermes_cli/auth_commands.py,hermes_cli/main.py,hermes_cli/model_switch.pyShow the diff
-
hermes_cli/auth_commands.py@@ -4,6 +4,7 @@ from getpass import getpass import math +import sys import time from types import SimpleNamespace import uuid @@ -160,7 +161,10 @@ def auth_add_command(args) -> None: default_label = _api_key_default_label(len(pool.entries()) + 1) label = (getattr(args, "label", None) or "").strip() if not label: - label = input(f"Label (optional, default: {default_label}): ").strip() or default_label + if sys.stdin.isatty(): + label = input(f"Label (optional, default: {default_label}): ").strip() or default_label + else: + label = default_label entry = PooledCredential( provider=provider, id=uuid.uuid4().hex[:6], -
hermes_cli/main.py@@ -6325,8 +6325,13 @@ def cmd_acp(args): sys.stderr = _io.StringIO() args = parser.parse_args(_processed_argv) sys.stderr = _saved_stderr - except SystemExit: + except SystemExit as exc: sys.stderr = _saved_stderr + # Help/version flags (exit code 0) already printed output — + # re-raise immediately to avoid a second parse_args printing + # the same help text again (#10230). + if exc.code == 0: + raise # Subcommand name was consumed as a flag value (e.g. -c model). # Fall back to optional subparsers so argparse handles it normally. subparsers.required = False -
hermes_cli/model_switch.py@@ -786,7 +786,8 @@ def list_authenticated_providers( from hermes_cli.models import OPENROUTER_MODELS, _PROVIDER_MODELS results: List[dict] = [] - seen_slugs: set = set() + seen_slugs: set = set() # lowercase-normalized to catch case variants (#9545) + seen_mdev_ids: set = set() # prevent duplicate entries for aliases (e.g. kimi-coding + kimi-coding-cn) data = fetch_models_dev() @@ -799,6 +800,11 @@ def list_authenticated_providers( # --- 1. Check Hermes-mapped providers --- for hermes_id, mdev_id in PROVIDER_TO_MODELS_DEV.items(): + # Skip aliases that map to the same models.dev provider (e.g. + # kimi-coding and kimi-coding-cn both → kimi-for-coding). + # The first one with valid credentials wins (#10526). + if mdev_id in seen_mdev_ids: + continue pdata = data.get(mdev_id) if not isinstance(pdata, dict): continue @@ -837,7 +843,8 @@ def list_authenticated_providers( "total_models": total, "source": "built-in", }) - seen_slugs.add(slug) + seen_slugs.add(slug.lower()) + seen_mdev_ids.add(mdev_id) # --- 2. Check Hermes-only providers (nous, openai-codex, copilot, opencode-go) --- from hermes_cli.providers import HERMES_OVERLAYS @@ -849,12 +856,12 @@ def list_authenticated_providers( _mdev_to_hermes = {v: k for k, v in PROVIDER_TO_MODELS_DEV.items()} for pid, overlay in HERMES_OVERLAYS.items(): - if pid in seen_slugs: + if pid.lower() in seen_slugs: continue # Resolve Hermes slug — e.g. "github-copilot" → "copilot" hermes_slug = _mdev_to_hermes.get(pid, pid) - if hermes_slug in seen_slugs: + if hermes_slug.lower() in seen_slugs: continue # Check if credentials exist @@ -935,8 +942,8 @@ def list_authenticated_providers( "total_models": total, "source": "hermes", }) - seen_slugs.add(pid) - seen_slugs.add(hermes_slug) + seen_slugs.add(pid.lower()) + seen_slugs.add(hermes_slug.lower()) # --- 2b. Cross-check canonical provider list --- # Catches providers that are in CANONICAL_PROVIDERS but weren't found @@ -948,7 +955,7 @@ def list_authenticated_providers( _canon_provs = [] for _cp in _canon_provs: - if _cp.slug in seen_slugs: + if _cp.slug.lower() in seen_slugs: continue # Check credentials via PROVIDER_REGISTRY (auth.py) @@ -995,7 +1002,7 @@ def list_authenticated_providers( "total_models": _cp_total, "source": "canonical", }) - seen_slugs.add(_cp.slug) + seen_slugs.add(_cp.slug.lower()) # --- 3. User-defined endpoints from config --- if user_providers and isinstance(user_providers, dict): @@ -1068,7 +1075,7 @@ def list_authenticated_providers( groups[slug]["models"].append(default_model) for slug, grp in groups.items(): - if slug in seen_slugs: + if slug.lower() in seen_slugs: continue results.append({ "slug": slug, @@ -1080,7 +1087,7 @@ def list_authenticated_providers( "source": "user-config", "api_url": grp["api_url"], }) - seen_slugs.add(slug) + seen_slugs.add(slug.lower()) # Sort: current provider first, then by model count descending results.sort(key=lambda r: (not r["is_current"], -r["total_models"]))
-
1 PR closed without merging
From the close comments: merged via another change 1
-
#10475 fix(auth): use default label silently in non-interactive environments · merged via another change →
b750c72,#10468,#10230,#10526,#9545,#10599
Closed issues · 1
- Closed#10468Bug: hermes auth add api_key crashes on non-interactive label prompt
How this cluster was grouped
-
Link evidence (
structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference. -
Pairwise link density
0.67: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Merged PRs
- #10599
- Closed issues
- 1
- Attempts
- 1 PR closed without merging
- Fix link checked
- 16 Apr 2026. This confirmation is old and may be out of date (a revert or reopen would not have invalidated it here); re-verify.