Gemini auth method fixes in doctor/discovery
NousResearch/hermes-agent · cluster 19837 · agent
Data as of
4 open items. Fix merged in #11961. Check it covers your case.
The short answer
- Known?
- Yes. 30 related items grouped here, 10 issues already closed.
- Fix event
- A fix was merged to main in PR #11961. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
partially resolved, deciding PR #22801. That is separate from the fix event. - Still open
- 2 issues and 2 PRs.
Next step: read #11961, then check whether your report is one of the 2 still open.
Read #11961Pick up a Lab taskThese issues and PRs center on incorrect authentication formats (Bearer token vs. API key query param or x-goog-api-key header) being used when probing or discovering Gemini endpoints in the doctor command and model discovery. Multiple related fixes address false-positive invalid-key errors and routing to the correct Gemini API endpoint.
Open issues2
Open PRs2
Fixes on record
-
#11961 fix(gemini): route Google AI Studio auth via x-goog-api-key header (#7893)
files:
agent/auxiliary_client.py,run_agent.py,scripts/release.py,tests/hermes_cli/test_gemini_provider.py -
#22801 fix(doctor): skip pluggable provider profiles when a dedicated check exists (salvage #22529)
files:
hermes_cli/doctor.py,tests/hermes_cli/test_doctor_dedicated_provider_skip.pyShow the diff
-
hermes_cli/doctor.py@@ -245,15 +245,31 @@ def _build_apikey_providers_list() -> list: } for _label, _canonical in _name_to_canonical.items(): _known_canonical.add(_canonical) + # Providers that already have a dedicated health check above the generic + # API-key loop (with custom headers/auth). Skip their pluggable profiles + # here so the generic Bearer-auth loop doesn't run a duplicate, broken + # check (e.g. Anthropic native API requires x-api-key, not Bearer). + _dedicated_canonical = {"anthropic", "openrouter", "bedrock"} + _known_canonical.update(_dedicated_canonical) try: from providers import list_providers from providers.base import ProviderProfile as _PP + try: + from hermes_cli.providers import normalize_provider as _normalize_provider + except Exception: # pragma: no cover - normalization is best-effort + def _normalize_provider(_name: str) -> str: + return (_name or "").strip().lower() for _pp in list_providers(): if not isinstance(_pp, _PP) or _pp.auth_type != "api_key" or not _pp.env_vars: continue _label = _pp.display_name or _pp.name if _label in _known_names or _pp.name in _known_canonical: continue + _candidates = {_normalize_provider(_pp.name)} + for _alias in (_pp.aliases or ()): + _candidates.add(_normalize_provider(_alias)) + if _candidates & _dedicated_canonical: + continue # Separate API-key vars from base-URL override vars — the health-check # loop sends the first found value as Authorization: Bearer, so a URL # string must never be picked. -
tests/hermes_cli/test_doctor_dedicated_provider_skip.py@@ -0,0 +1,50 @@ +"""Regression: hermes doctor must not run a generic Bearer-auth health +check for providers that already have a dedicated check (Anthropic, +OpenRouter, Bedrock). + +Anthropic's native API requires `x-api-key` + `anthropic-version` headers; +the generic loop sends `Authorization: Bearer ...` which Anthropic answers +with HTTP 404. The dedicated check at hermes_cli/doctor.py already covers +Anthropic with the right headers, so the pluggable profile must be +skipped by `_build_apikey_providers_list()`. + +See: NousResearch/hermes-agent#22346 +""" + +from __future__ import annotations + + +def test_build_apikey_providers_list_skips_dedicated_check_providers(): + from hermes_cli import doctor + + # Force a rebuild — the module caches the list on first call. + doctor._APIKEY_PROVIDERS_CACHE = None + entries = doctor._build_apikey_providers_list() + + # Tuple shape: (display_name, env_vars, default_url, base_env, supports_health_check) + names = {entry[0].lower() for entry in entries} + assert not any("anthropic" in name for name in names), ( + f"Anthropic provider profile leaked into generic Bearer-auth health " + f"check loop. Dedicated check above already covers it with " + f"x-api-key headers. Got entries: {sorted(names)}" + ) + assert not any("openrouter" in name for name in names), ( + f"OpenRouter has a dedicated check; generic loop must skip it. " + f"Got: {sorted(names)}" + ) + assert not any("bedrock" in name for name in names), ( + f"Bedrock uses AWS SDK creds, not Bearer auth; generic loop must skip. " + f"Got: {sorted(names)}" + ) + + +def test_build_apikey_providers_list_includes_non_dedicated_providers(): + """Sanity guard: the skip-set must not strip every provider.""" + from hermes_cli import doctor + + doctor._APIKEY_PROVIDERS_CACHE = None + entries = doctor._build_apikey_providers_list() + + names = {entry[0] for entry in entries} + assert "DeepSeek" in names + assert "Z.AI / GLM" in names
-
14 PRs closed without merging
From the close comments: superseded by another PR 5 · done elsewhere 3 · duplicate 3 · merged via another change 1 · other 2
-
#19854 fix(doctor): report google/gemini API key status in connectivity checks · superseded by another PR →
#20204 - #20204 doctor: report Google Gemini API connectivity · done elsewhere
-
#20935 fix(doctor): skip /models health-check for Alibaba dedicated tiers · other →
#20642 -
#21490 fix(doctor): validate Gemini keys with Google auth · done elsewhere →
364a1dd -
#22232 fix: align doctor provider health checks · other →
0c233e7,6b21a93
Show 9 more
- #22286 fix(doctor): probe native gemini keys correctly · done elsewhere
-
#22367 fix(doctor): skip duplicate anthropic Bearer-auth check · superseded by another PR →
#22529,#22346 -
#22512 fix(cli): skip dedicated-check providers in apikey loop · superseded by another PR →
#22801,#22529 -
#22529 fix(doctor): skip pluggable provider profiles when a dedicated check exists (#22346) · merged via another change →
#22801 -
#23364 fix(doctor): use ?key= auth for Gemini API key validation · superseded by another PR →
#11961 - #25139 fix: use Gemini API key query auth in doctor · superseded by another PR
-
#26784 fix(doctor): use query-param auth for Gemini in API-key probe · duplicate →
#21058,#20642,#21490,#22286,#22468,#23364,#24033,#24266,#26067 -
#26922 fix(doctor): use x-goog-api-key for Gemini connectivity probe (#26623) · duplicate →
#20642,#22468,#22489,#24266,#25883,#26067 -
#62267 fix(providers): use native query-param auth for Gemini model discovery (#62259) · duplicate →
#42693,#62259
Closed issues · 10
- Closed#19837[Bug]: cli doctor API Connectivity missing google api key/gemini api key
- Closed#21058hermes doctor: Gemini healthcheck fails with 401 due to Bearer-token auth incompatibility
- Closed#21481[Bug]: hermes doctor falsely reports valid Google AI Studio Gemini API key as invalid
- Closed#22223doctor should honor provider base URL overrides for Xiaomi health checks
- Closed#22346hermes doctor: duplicate `anthropic` check fails with HTTP 404 (wrong auth header in pluggable provider check)
- Closed#23354Hermes Doctor flags Google Gemini API key as invalid even when the key works
- Closed#25108[Bug]: hermes doctor validates Gemini API keys with Bearer auth instead of ?key=
- Closed#26284hermes doctor reports false positive "invalid API key" for Google Gemini
- Closed#26623[Bug]: bug(cli): hermes doctor falsely reports Google Gemini API key as invalid (HTTP 401 due to OpenAI auth format)
- Closed#27310doctor should validate Gemini API keys with Gemini native auth instead of generic Bearer probe
How this cluster was grouped
-
Link evidence (
partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text. - Members outside that structural core may belong to a different underlying problem.
-
Pairwise link density
0.07: 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 Lab