From 18966b6244ecca6ae8ad4304457bf5f3a61b43a6 Mon Sep 17 00:00:00 2001 From: charliekerfoot Date: Mon, 27 Apr 2026 18:07:11 -0500 Subject: [PATCH] fix(credential_pool): match Anthropic OAuth tokens by sk-ant-oat prefix --- agent/credential_pool.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/agent/credential_pool.py b/agent/credential_pool.py index 8d10bbb1cbf..da1f307284c 100644 --- a/agent/credential_pool.py +++ b/agent/credential_pool.py @@ -2162,7 +2162,17 @@ def _seed_from_env(provider: str, entries: List[PooledCredential]) -> Tuple[bool if _is_source_suppressed(provider, source): continue active_sources.add(source) - auth_type = AUTH_TYPE_OAUTH if provider == "anthropic" and not token.startswith("sk-ant-api") else AUTH_TYPE_API_KEY + # Claude Code OAuth tokens are the only Anthropic credentials that should + # flow into the OAuth refresh path. Match the `sk-ant-oat` prefix + # positively — matching by negation (everything not `sk-ant-api`) wrongly + # tagged admin keys (`sk-ant-admin*`) and any future API-key prefix as + # OAuth, which then got immediately marked exhausted on first use because + # they have no refresh token. + auth_type = ( + AUTH_TYPE_OAUTH + if provider == "anthropic" and token.startswith("sk-ant-oat") + else AUTH_TYPE_API_KEY + ) base_url = env_url or pconfig.inference_base_url if provider == "kimi-coding": base_url = _resolve_kimi_base_url(token, pconfig.inference_base_url, env_url)