{"record":{"id":"ca0ea503c5292138","repo":"NousResearch/hermes-agent","slug":"provider-explicit-is-set-in-config-yaml-but-n-ca0ea5","errorCode":null,"errorMessage":"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`.","messagePattern":"Provider '(.+?)' is set in config\\.yaml but no API key was found\\. Set the (.+?)_API_KEY environment variable, or switch to a different provider with `hermes model`\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agent/auxiliary_client.py","lineNumber":9161,"sourceCode":"            client, resolved_provider,\n        )\n        if client is None:\n            # When the user explicitly chose a non-OpenRouter provider but no\n            # credentials were found, honor the task fallback_chain before\n            # raising.  Missing raw env keys are recoverable for auxiliary\n            # tasks because fallback entries may use OAuth / credential-pool\n            # auth (for example openai-codex).\n            _explicit = (resolved_provider or \"\").strip().lower()\n            if _explicit and _explicit not in {\"auto\", \"openrouter\", \"custom\"}:\n                fb_client, fb_model, fb_label = _try_configured_fallback_for_unavailable_client(\n                    task, _explicit,\n                )\n                if fb_client is not None:\n                    client, final_model = fb_client, fb_model\n                    resolved_provider = fb_label or resolved_provider\n                    effective_provider = resolved_provider\n                else:\n                    raise RuntimeError(\n                        f\"Provider '{_explicit}' is set in config.yaml but no API key \"\n                        f\"was found. Set the {_explicit.upper()}_API_KEY environment \"\n                        f\"variable, or switch to a different provider with `hermes model`.\"\n                    )\n            # For auto/custom with no credentials, try the full auto chain\n            # rather than hardcoding OpenRouter (which may be depleted).\n            # Pass model=None so each provider uses its own default —\n            # resolved_model may be an OpenRouter-format slug that doesn't\n            # work on other providers.\n            if client is None and not resolved_base_url:\n                logger.info(\"Auxiliary %s: provider %s unavailable, trying auto-detection chain\",\n                            task or \"call\", resolved_provider)\n                client, final_model = _get_cached_client(\n                    \"auto\", main_runtime=main_runtime, task=task,\n                )\n                effective_provider = _effective_provider_for_client(\n                    client, \"auto\",\n                )","sourceCodeStart":9143,"sourceCodeEnd":9179,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/agent/auxiliary_client.py#L9143-L9179","documentation":"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.","triggerScenarios":"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.","commonSituations":"User copied config.yaml to a new machine without .env; key name typo; provider key revoked; profile switched but .env not migrated.","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."],"exampleFix":"# ~/.hermes/.env — before (missing) / after\n# before: (no GROQ_API_KEY entry)\n# after:\nGROQ_API_KEY=gsk_your_key_here","handlingStrategy":"validation","validationCode":"import os\nprovider = \"groq\"  # whatever config.yaml names\nassert os.getenv(f\"{provider.upper()}_API_KEY\"), f\"{provider.upper()}_API_KEY missing — set it in ~/.hermes/.env\"","typeGuard":null,"tryCatchPattern":"try:\n    result = aux_call(...)\nexcept RuntimeError as e:\n    if \"no API key was found\" in str(e):\n        prompt_user_for_key(provider); return None","preventionTips":["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."],"tags":["auxiliary","credentials","configuration","env"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}