{"repo":"NousResearch/hermes-agent","public_id":"3233","display_label":"Background review agent missing custom provider credentials","summary":"Multiple reports and fixes address background review agents failing when custom API endpoints, api_key, or base_url are not forwarded from the parent agent's configuration. Covers 403 errors, missing provider config, and related credential propagation issues.","subsystem":"agent","counts":{"members":8,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":4,"merged_prs":1,"attempt_prs":3},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":16099},"resolution":{"state":"unresolved","by":null},"freshness":{"state":"verified","last_verified_at":"2026-04-26T15:29:40+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_PARTIAL","link_density":0.2914285714285714},"fix_edges":[{"issue_number":3233,"pr_number":16099,"tier":"verified","basis":"superseded_ref","confidence":0.9,"recoverable_from_timeline":false},{"issue_number":8517,"pr_number":16099,"tier":"verified","basis":"superseded_ref","confidence":0.9,"recoverable_from_timeline":false},{"issue_number":15543,"pr_number":16099,"tier":"verified","basis":"superseded_ref","confidence":0.9,"recoverable_from_timeline":false},{"issue_number":15882,"pr_number":16099,"tier":"verified","basis":"superseded_ref","confidence":0.9,"recoverable_from_timeline":false}],"members":[{"kind":"issue","number":3233,"title":"[Bug]: Background review agents get 403 on providers with custom API endpoints","url":null,"state":"closed"},{"kind":"issue","number":15543,"title":"Background Review Agent Fails with Custom Providers (Missing api_key/base_url)","url":null,"state":"closed"},{"kind":"issue","number":15882,"title":"_spawn_background_review doesn't pass base_url / api_key — context length detection fails for custom/fallback endpoints","url":null,"state":"closed"},{"kind":"issue","number":16123,"title":"Bug: Background review fails with No LLM provider configured when using custom providers","url":null,"state":"closed"},{"kind":"pr","number":3235,"title":"Fix background review 403","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"e3901d5b2","number":0},{"kind":"pr","value":"#3233","number":3233},{"kind":"pr","value":"#16099","number":16099},{"kind":"pr","value":"#3210","number":3210}],"category":"implemented_elsewhere","implication":"superseded"},"merged":false},{"kind":"pr","number":15645,"title":"fix(run_agent): forward api_key/base_url/api_mode to background review agent (#15543)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#16099","number":16099},{"kind":"pr","value":"#15645","number":15645},{"kind":"pr","value":"#16099","number":16099}],"category":"superseded_by_pr","implication":"superseded"},"merged":false},{"kind":"pr","number":15884,"title":"fix: pass base_url and api_key to background review AIAgent","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"e3901d5b257d5ac3f58420c3fb55aaa536fc56ac","number":0},{"kind":"pr","value":"#16099","number":16099},{"kind":"pr","value":"#15645","number":15645}],"category":"implemented_elsewhere","implication":"superseded"},"merged":false},{"kind":"pr","number":16099,"title":"fix(run_agent): background review fork inherits parent's live runtime","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["run_agent.py"],"fix_hunks":[{"file":"run_agent.py","hunks":["@@ -3154,12 +3154,25 @@ def _run_review():\n                 with open(os.devnull, \"w\") as _devnull, \\\n                      contextlib.redirect_stdout(_devnull), \\\n                      contextlib.redirect_stderr(_devnull):\n+                    # Inherit the parent agent's live runtime (provider, model,\n+                    # base_url, api_key, api_mode) so the fork uses the exact\n+                    # same credentials the main turn is using.  Without this,\n+                    # AIAgent.__init__ re-runs auto-resolution from env vars,\n+                    # which fails for OAuth-only providers, session-scoped\n+                    # creds, or credential-pool setups where the resolver can't\n+                    # reconstruct auth from scratch -- producing the spurious\n+                    # \"No LLM provider configured\" warning at end of turn.\n+                    _parent_runtime = self._current_main_runtime()\n                     review_agent = AIAgent(\n                         model=self.model,\n                         max_iterations=8,\n                         quiet_mode=True,\n                         platform=self.platform,\n                         provider=self.provider,\n+                        api_mode=_parent_runtime.get(\"api_mode\") or None,\n+                        base_url=_parent_runtime.get(\"base_url\") or None,\n+                        api_key=[redacted:secret-assignment]\"api_key\") or None,\n+                        credential_pool=[redacted:secret-assignment] \"_credential_pool\", None),\n                         parent_session_id=self.session_id,\n                     )\n                     review_agent._memory_write_origin = \"background_review\"\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}