NousResearch/hermes-agent

OpenRouter exhausted auxiliary key logging clarification

Cluster 14618. Data as of

Nothing open on GitHub. Fix merged in #14739 on 23 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 #14739. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PR #14739. That is separate from the fix event.
Still open
Nothing open on GitHub.

A bug was reported where an exhausted OpenRouter auxiliary API key was incorrectly logged as the key not being set. These members address clarifying the error message to accurately reflect the exhausted credential state.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #14739 fix(agent): clarify exhausted OpenRouter auxiliary credentials (salvage #14646)

    merged to main

    files: agent/auxiliary_client.py, tests/agent/test_auxiliary_client.py

    Show the diff
    • agent/auxiliary_client.py
      @@ -916,6 +916,19 @@ def _try_openrouter() -> Tuple[Optional[OpenAI], Optional[str]]:
                          default_headers=_OR_HEADERS), _OPENROUTER_MODEL
       
       
      +def _describe_openrouter_unavailable() -> str:
      +    """Return a more precise OpenRouter auth failure reason for logs."""
      +    pool_present, entry = _select_pool_entry("openrouter")
      +    if pool_present:
      +        if entry is None:
      +            return "OpenRouter credential pool has no usable entries (credentials may be exhausted)"
      +        if not _pool_runtime_api_key(entry):
      +            return "OpenRouter credential pool entry is missing a runtime API key"
      +    if not str(os.getenv("OPENROUTER_API_KEY") or "").strip():
      +        return "OPENROUTER_API_KEY not set"
      +    return "no usable OpenRouter credentials found"
      +
      +
       def _try_nous(vision: bool = False) -> Tuple[Optional[OpenAI], Optional[str]]:
           # Check cross-session rate limit guard before attempting Nous —
           # if another session already recorded a 429, skip Nous entirely
      @@ -1627,8 +1640,10 @@ def _wrap_if_needed(client_obj, final_model_str: str, base_url_str: str = ""):
           if provider == "openrouter":
               client, default = _try_openrouter()
               if client is None:
      -            logger.warning("resolve_provider_client: openrouter requested "
      -                           "but OPENROUTER_API_KEY not set")
      +            logger.warning(
      +                "resolve_provider_client: openrouter requested but %s",
      +                _describe_openrouter_unavailable(),
      +            )
                   return None, None
               final_model = _normalize_resolved_model(model or default, provider)
               return (_to_async_client(client, final_model) if async_mode
    • tests/agent/test_auxiliary_client.py
      @@ -447,6 +447,34 @@ def test_explicit_anthropic_api_key(self, monkeypatch):
                   adapter = client.chat.completions
                   assert adapter._is_oauth is False
       
      +    def test_explicit_openrouter_pool_exhausted_logs_precise_warning(self, monkeypatch, caplog):
      +        monkeypatch.delenv("OPENROUTER_API_KEY", raising=False)
      +        with patch("agent.auxiliary_client._select_pool_entry", return_value=(True, None)):
      +            with caplog.at_level(logging.WARNING, logger="agent.auxiliary_client"):
      +                client, model = resolve_provider_client("openrouter")
      +        assert client is None
      +        assert model is None
      +        assert any(
      +            "credential pool has no usable entries" in record.message
      +            for record in caplog.records
      +        )
      +        assert not any(
      +            "OPENROUTER_API_KEY not set" in record.message
      +            for record in caplog.records
      +        )
      +
      +    def test_explicit_openrouter_missing_env_keeps_not_set_warning(self, monkeypatch, caplog):
      +        monkeypatch.delenv("OPENROUTER_API_KEY", raising=False)
      +        with patch("agent.auxiliary_client._select_pool_entry", return_value=(False, None)):
      +            with caplog.at_level(logging.WARNING, logger="agent.auxiliary_client"):
      +                client, model = resolve_provider_client("openrouter")
      +        assert client is None
      +        assert model is None
      +        assert any(
      +            "OPENROUTER_API_KEY not set" in record.message
      +            for record in caplog.records
      +        )
      +
       class TestGetTextAuxiliaryClient:
           """Test the full resolution chain for get_text_auxiliary_client."""
       

1 PR closed without merging

From the close comments: closed without comment 1

  • #14646 fix(agent): clarify exhausted OpenRouter auxiliary credentials · closed without comment
Closed issues · 1
  • Closed#14618[Bug]: In auxiliary client, an exhausted OpenRouter key is logged as key not being set
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.00 means 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

At a glance

Merged PRs
#14739
Closed issues
1
Attempts
1 PR closed without merging
Fix link checked
23 Apr 2026. This confirmation is old and may be out of date (a revert or reopen would not have invalidated it here); re-verify.

For your agent

The same facts, typed.