NousResearch/hermes-agent · error · RuntimeError
Provider '{_explicit}' is set in config.yaml but no API key
Error message
Provider '{_explicit}' is set in config.yaml but no API key was found. Set the {_explicit.upper()}_API_KEY environment variable, or switch to a different provider with `hermes model`. What it means
The synchronous auxiliary path found the client unavailable for an explicitly configured provider (not auto/openrouter/custom). It tried _try_configured_fallback_for_unavailable_client() to find a configured fallback (which may use OAuth/credential-pool auth like openai-codex); no fallback matched, so it reports the concrete missing credential: the PROVIDER_API_KEY env var.
Source
Thrown at agent/auxiliary_client.py:9161
client, resolved_provider,
)
if client is None:
# When the user explicitly chose a non-OpenRouter provider but no
# credentials were found, honor the task fallback_chain before
# raising. Missing raw env keys are recoverable for auxiliary
# tasks because fallback entries may use OAuth / credential-pool
# auth (for example openai-codex).
_explicit = (resolved_provider or "").strip().lower()
if _explicit and _explicit not in {"auto", "openrouter", "custom"}:
fb_client, fb_model, fb_label = _try_configured_fallback_for_unavailable_client(
task, _explicit,
)
if fb_client is not None:
client, final_model = fb_client, fb_model
resolved_provider = fb_label or resolved_provider
effective_provider = resolved_provider
else:
raise RuntimeError(
f"Provider '{_explicit}' is set in config.yaml but no API key "
f"was found. Set the {_explicit.upper()}_API_KEY environment "
f"variable, or switch to a different provider with `hermes model`."
)
# For auto/custom with no credentials, try the full auto chain
# rather than hardcoding OpenRouter (which may be depleted).
# Pass model=None so each provider uses its own default —
# resolved_model may be an OpenRouter-format slug that doesn't
# work on other providers.
if client is None and not resolved_base_url:
logger.info("Auxiliary %s: provider %s unavailable, trying auto-detection chain",
task or "call", resolved_provider)
client, final_model = _get_cached_client(
"auto", main_runtime=main_runtime, task=task,
)
effective_provider = _effective_provider_for_client(
client, "auto",
)View on GitHub (pinned to c896c09c42)
Solutions
- Add the key to ~/.hermes/.env: e.g. `GROQ_API_KEY=sk-...` (exact name is shown uppercased in the message).
- Or switch the provider: `hermes model` and pick one you have credentials for.
- Or set `auxiliary.<task>.provider: auto` to let the auto-detection chain pick any available provider.
- Run `hermes setup` to be prompted for the missing key.
Example fix
# ~/.hermes/.env — before (missing) / after # before: (no GROQ_API_KEY entry) # after: GROQ_API_KEY=gsk_your_key_here
Defensive patterns
Strategy: validation
Validate before calling
import os
provider = "groq" # whatever config.yaml names
assert os.getenv(f"{provider.upper()}_API_KEY"), f"{provider.upper()}_API_KEY missing — set it in ~/.hermes/.env" Try / catch
try:
result = aux_call(...)
except RuntimeError as e:
if "no API key was found" in str(e):
prompt_user_for_key(provider); return None Prevention
- Whenever config.yaml names a provider, immediately add its PROVIDER_API_KEY to .env.
- Copy .env alongside config.yaml when migrating machines.
- Run `hermes setup` after any provider change.
When it happens
Trigger: config.yaml (or auxiliary.<task>.provider / model.provider) names e.g. 'groq' but GROQ_API_KEY is not in ~/.hermes/.env and no fallback provider is usable.
Common situations: User copied config.yaml to a new machine without .env; key name typo; provider key revoked; profile switched but .env not migrated.
Related errors
- No LLM provider configured for task={task} provider={resolve
- Auxiliary {task or 'call'}: provider {resolved_provider} cou
- SSH remote mode is selected but no host is configured.
- Could not create directory: ${error.message}
- No available openai-codex credential in credential pool
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/ca0ea503c5292138.
Report an issue: GitHub.