From 32f7c5afaff4f4ac6c6b13cfe026df61b6296941 Mon Sep 17 00:00:00 2001 From: annguyenNous Date: Fri, 5 Jun 2026 08:00:29 +0700 Subject: [PATCH] fix(gateway): distinguish gateway auth 401 from provider API key errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The api_server adapter returned error code "invalid_api_key" for API_SERVER_KEY authentication failures, which the Desktop error classifier misidentified as a provider (OpenRouter/OpenAI) key problem — showing "OpenRouter API key missing" when the real issue was gateway auth. Changes: - gateway/platforms/api_server.py: return "gateway_auth_failed" code with descriptive message for API_SERVER_KEY auth failures - apps/desktop/src/store/notifications.ts: add "gateway_auth_failed" handler before "invalid_api_key" to show correct error message - agent/error_classifier.py: add "gateway_auth_failed" to auth patterns - tests: update test_session_api.py to expect new error code Fixes #39365 --- agent/error_classifier.py | 1 + apps/desktop/src/store/notifications.ts | 6 +++++- gateway/platforms/api_server.py | 2 +- tests/gateway/test_session_api.py | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/agent/error_classifier.py b/agent/error_classifier.py index 9d830cdc996..33c2f545856 100644 --- a/agent/error_classifier.py +++ b/agent/error_classifier.py @@ -413,6 +413,7 @@ _CONTENT_POLICY_BLOCKED_PATTERNS = [ _AUTH_PATTERNS = [ "invalid api key", "invalid_api_key", + "gateway_auth_failed", "authentication", "unauthorized", "forbidden", diff --git a/apps/desktop/src/store/notifications.ts b/apps/desktop/src/store/notifications.ts index 92f41163506..97bfc31d541 100644 --- a/apps/desktop/src/store/notifications.ts +++ b/apps/desktop/src/store/notifications.ts @@ -78,7 +78,11 @@ function cleanErrorText(value: string) { const ERROR_SUMMARIES: { test: (msg: string) => boolean; summarize: (msg: string) => string }[] = [ { - test: msg => /incorrect api key provided/i.test(msg) || /['"]code['"]\s*:\s*['"]invalid_api_key['"]/i.test(msg), + test: msg => /['"']code['"']\s*:\s*['"']gateway_auth_failed['"']/i.test(msg), + summarize: () => 'Gateway authentication failed — check your API_SERVER_KEY.' + }, + { + test: msg => /incorrect api key provided/i.test(msg) || /['"']code['"']\s*:\s*['"']invalid_api_key['"']/i.test(msg), summarize: msg => { const status = msg.match(/(?:error code|status(?:Code)?)[^\d]*(\d{3})/i)?.[1] diff --git a/gateway/platforms/api_server.py b/gateway/platforms/api_server.py index f2af8566639..c888fef3d3b 100644 --- a/gateway/platforms/api_server.py +++ b/gateway/platforms/api_server.py @@ -1335,7 +1335,7 @@ class APIServerAdapter(BasePlatformAdapter): self._request_audit_log_suffix(request), ) return web.json_response( - {"error": {"message": "Invalid API key", "type": "invalid_request_error", "code": "invalid_api_key"}}, + {"error": {"message": "Invalid gateway API key (API_SERVER_KEY)", "type": "gateway_auth_error", "code": "gateway_auth_failed"}}, status=401, ) diff --git a/tests/gateway/test_session_api.py b/tests/gateway/test_session_api.py index 47f7b38eec4..ac6314f2d28 100644 --- a/tests/gateway/test_session_api.py +++ b/tests/gateway/test_session_api.py @@ -416,7 +416,7 @@ async def test_session_endpoints_require_auth_when_key_configured(auth_adapter): resp = await cli.get("/api/sessions") assert resp.status == 401 body = await resp.json() - assert body["error"]["code"] == "invalid_api_key" + assert body["error"]["code"] == "gateway_auth_failed" ok = await cli.get("/api/sessions", headers={"Authorization": "Bearer sk-test"}) assert ok.status == 200