From ce6fd374765706fc2aae64ffc9dd0179cb75abff Mon Sep 17 00:00:00 2001 From: Markus Hartung Date: Thu, 20 Aug 2026 06:32:41 -0300 Subject: [PATCH] test: realign no-credentials status expectations to 401 for single-model requests This PR's own handleNoCredentials change remaps the leaked combo-fallback 404 to 401 for non-combo (single-model) requests, but left 5 pre-existing tests asserting the old 404 for exactly that single-model path: vscode-token-routes.test.ts (both routes), chat-route-coverage.test.ts, chat-pipeline.test.ts (both cases), combo-routing-e2e.test.ts (unmapped-model case), llama-cpp-provider.test.ts. Combo-routing tests that legitimately expect 404 (isCombo=true fall-through) are untouched. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --- tests/integration/chat-pipeline.test.ts | 6 ++++-- tests/integration/combo-routing-e2e.test.ts | 6 ++++-- tests/integration/llama-cpp-provider.test.ts | 5 +++-- tests/unit/chat-route-coverage.test.ts | 12 +++++++----- tests/unit/vscode-token-routes.test.ts | 16 ++++++++-------- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/tests/integration/chat-pipeline.test.ts b/tests/integration/chat-pipeline.test.ts index d37fa02a51..382dd00b6b 100644 --- a/tests/integration/chat-pipeline.test.ts +++ b/tests/integration/chat-pipeline.test.ts @@ -1112,7 +1112,8 @@ test("chat pipeline allows unauthenticated requests through to provider resoluti // handleChat does not enforce REQUIRE_API_KEY — that's the authz pipeline's job. // Without provider credentials seeded, the request falls through to the "no credentials" path. // Upstream port decolua/9router#336: 400 → 404 so combo routing can fall through. - assert.equal(response.status, 404); + // #10797: single-model (non-combo) no-credentials now remaps 404 → 401. + assert.equal(response.status, 401); assert.match(json.error.message, /No active credentials for provider/i); }); @@ -1231,7 +1232,8 @@ test("chat pipeline returns current no-credentials contract when no provider con const json = (await response.json()) as any; // Upstream port decolua/9router#336: 400 → 404 so combo routing can fall through. - assert.equal(response.status, 404); + // #10797: single-model (non-combo) no-credentials now remaps 404 → 401. + assert.equal(response.status, 401); assert.match(json.error.message, /No active credentials for provider: openai/); }); diff --git a/tests/integration/combo-routing-e2e.test.ts b/tests/integration/combo-routing-e2e.test.ts index fea0c16b8a..cd8e046ee0 100644 --- a/tests/integration/combo-routing-e2e.test.ts +++ b/tests/integration/combo-routing-e2e.test.ts @@ -365,8 +365,10 @@ test("unmapped custom model requests fail after combo resolution falls through", const json = (await response.json()) as any; // Upstream port decolua/9router#336: 400 → 404 so combo routing can fall through - // to the next target when a provider has zero usable credentials. - assert.equal(response.status, 404); + // to the next target when a provider has zero usable credentials. This request + // never resolves to a combo target (unmapped model), so it takes the + // single-model path — #10797 remaps that 404 → 401. + assert.equal(response.status, 401); assert.match(json.error.message, /No active credentials for provider: tenant/); }); diff --git a/tests/integration/llama-cpp-provider.test.ts b/tests/integration/llama-cpp-provider.test.ts index 3c87261d32..7c1cf517d1 100644 --- a/tests/integration/llama-cpp-provider.test.ts +++ b/tests/integration/llama-cpp-provider.test.ts @@ -171,8 +171,9 @@ test("llama-cpp provider: alias matching works via model catalog prefix", async assert.equal(json.choices[0].message.content, "42"); }); -test("llama-cpp provider: returns 404 when no connection exists", async () => { +test("llama-cpp provider: returns 401 when no connection exists", async () => { // Upstream port decolua/9router#336: 400 → 404 so combo routing can fall through. + // #10797: single-model (non-combo) no-credentials now remaps 404 → 401. const response = await handleChat( buildRequest({ body: { @@ -183,7 +184,7 @@ test("llama-cpp provider: returns 404 when no connection exists", async () => { }) ); - assert.equal(response.status, 404); + assert.equal(response.status, 401); const json = (await response.json()) as any; assert.match(json.error.message, /No active credentials for provider/); }); diff --git a/tests/unit/chat-route-coverage.test.ts b/tests/unit/chat-route-coverage.test.ts index e0b71badc9..0b8d4c8806 100644 --- a/tests/unit/chat-route-coverage.test.ts +++ b/tests/unit/chat-route-coverage.test.ts @@ -357,11 +357,13 @@ test("handleChat keeps the combo error when the global fallback throws", async ( assert.match(json.error.message, /primary combo failed/i); }); -test("handleChat returns 404 when no provider credentials exist", async () => { +test("handleChat returns 401 when no provider credentials exist (single-model)", async () => { // Upstream port decolua/9router#336 (Ibrahim Ryan): the no-credentials branch - // of handleNoCredentials now surfaces 404 NOT_FOUND so combo routing can fall - // through to the next target instead of being killed by the combo 400-hard-stop - // guard (open-sse/services/combo.ts, PR #4316 / issue #4279). + // of handleNoCredentials originally surfaced 404 NOT_FOUND unconditionally so + // combo routing could fall through to the next target (open-sse/services/combo.ts, + // PR #4316 / issue #4279). #10797 remaps that 404 to 401 for single-model + // (non-combo) requests — a direct client should see an auth/credential failure, + // not "not found"; combo routing still gets the 404 (see combo-routing-e2e.test.ts). const response = await handleChat( buildRequest({ body: { @@ -373,7 +375,7 @@ test("handleChat returns 404 when no provider credentials exist", async () => { ); const json = (await response.json()) as any; - assert.equal(response.status, 404); + assert.equal(response.status, 401); assert.match(json.error.message, /No active credentials for provider: openai/); }); diff --git a/tests/unit/vscode-token-routes.test.ts b/tests/unit/vscode-token-routes.test.ts index fe7fbf64d7..5a292b4600 100644 --- a/tests/unit/vscode-token-routes.test.ts +++ b/tests/unit/vscode-token-routes.test.ts @@ -1154,11 +1154,11 @@ test("vscode tokenized /chat/completions route applies the path token and codex ); const body = (await response.json()) as any; - // Upstream port decolua/9router#336: zero-active-credentials now surfaces as - // 404 (combo-fallbackable) instead of 400 (combo hard-stop). The 404 OpenAI - // error code mapping is "model_not_found" (open-sse/config/errorConfig.ts:29). - assert.equal(response.status, 404); - assert.equal(body.error?.code, "model_not_found"); + // #10797: zero-active-credentials for a single-model (non-combo) request now + // remaps to 401 instead of leaking the combo-fallback 404 to a direct client. + // The 401 OpenAI error code mapping is "invalid_api_key" (errorConfig.ts:26). + assert.equal(response.status, 401); + assert.equal(body.error?.code, "invalid_api_key"); assert.equal(body.error?.message, "No active credentials for provider: codex."); }); @@ -1187,9 +1187,9 @@ test("vscode tokenized /responses route applies the path token and codex tier re ); const body = (await response.json()) as any; - // Upstream port decolua/9router#336: see chat/completions sibling test above. - assert.equal(response.status, 404); - assert.equal(body.error?.code, "model_not_found"); + // #10797: see chat/completions sibling test above. + assert.equal(response.status, 401); + assert.equal(body.error?.code, "invalid_api_key"); assert.equal(body.error?.message, "No active credentials for provider: codex."); });