diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c9a42e0bd..b39a3b3546 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ ### 🔧 Bug Fixes +- **providers (onboarding wizard — unsupported validation):** adding a provider whose credentials have **no live validator** (LMArena, PiAPI, …) failed silently in the Add-Provider wizard. The `/api/providers/validate` endpoint returns `HTTP 400 + { unsupported: true }` for these (#5565/#5567), but the wizard's `validateOnboardingApiKey` ran it through `expectOk`, which threw on the non-200 — so the flow jumped to the error step and the connection was **never created**. The wizard now treats `unsupported: true` as a non-blocking "can't verify" and proceeds to save, mirroring `AddApiKeyModal`. Regression guard added to `tests/unit/provider-onboarding-wizard.test.ts`. (related to [#5692](https://github.com/diegosouzapw/OmniRoute/issues/5692)) + - **dashboard (Quick Start step 1):** the Quick Start "Create API key" step told users to "Go to **Endpoint** → Registered Keys" and linked to `/dashboard/endpoint`, but API keys are created on the **API Manager** page (`/dashboard/api-manager`, sidebar "API Keys") — the Endpoint page has no "Registered Keys" section, so users followed the link and could not find where to create a key. Step 1 now reads "Go to **API Keys**" and links to `/dashboard/api-manager`. Regression guard: `tests/unit/ui/quick-start-api-keys-link-5695.test.ts`. ([#5695](https://github.com/diegosouzapw/OmniRoute/issues/5695)) - **providers (DashScope/Alibaba setup link):** the "Get API key" link for the **Alibaba** and **Alibaba (China)** providers pointed at the bare API host (`dashscope-intl.aliyuncs.com` / `dashscope.aliyuncs.com`), which returns **404** in a browser — API hostnames have no homepage. Repointed to the consoles where keys are actually issued: `bailian.console.alibabacloud.com` (international) and `dashscope.console.aliyun.com` (China). Same class as #5572/#5574/#5576; regression guard added to `tests/unit/provider-setup-links-5572.test.ts`. ([#5665](https://github.com/diegosouzapw/OmniRoute/issues/5665)) diff --git a/src/app/(dashboard)/dashboard/providers/components/onboarding/providerOnboardingApi.ts b/src/app/(dashboard)/dashboard/providers/components/onboarding/providerOnboardingApi.ts index 3fe1bcf324..1882ac67ca 100644 --- a/src/app/(dashboard)/dashboard/providers/components/onboarding/providerOnboardingApi.ts +++ b/src/app/(dashboard)/dashboard/providers/components/onboarding/providerOnboardingApi.ts @@ -161,10 +161,18 @@ export async function validateOnboardingApiKey( headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); - const data = await expectOk>( - response, - "Provider credentials are not valid" - ); + const data = await parseJson(response); + // #5565/#5567: providers with no live validator (lmarena, piapi, …) return + // HTTP 400 + { unsupported: true }. Treat "validation not supported" as a + // non-blocking "can't verify" and let the wizard proceed to save — mirror + // AddApiKeyModal. Without this short-circuit `expectOk` threw on the 400 and + // the onboarding wizard never created the connection (#5692). + if (data.unsupported === true) { + return data; + } + if (!response.ok) { + throw new Error(extractError(data, "Provider credentials are not valid")); + } if (data.valid === false) { throw new Error(extractError(data, "Provider credentials are not valid")); } diff --git a/tests/unit/provider-onboarding-wizard.test.ts b/tests/unit/provider-onboarding-wizard.test.ts index 80dc3689d7..adc78f768c 100644 --- a/tests/unit/provider-onboarding-wizard.test.ts +++ b/tests/unit/provider-onboarding-wizard.test.ts @@ -159,6 +159,29 @@ test("provider onboarding validation rejects HTTP 200 responses with valid false } }); +test("#5692 onboarding validation treats unsupported providers as non-blocking (save proceeds)", async () => { + const originalFetch = globalThis.fetch; + globalThis.fetch = async (url) => { + if (String(url) === "/api/providers/validate") { + // #5565/#5567: providers with no live validator (lmarena, piapi, …) return + // HTTP 400 + { unsupported: true }. The wizard must NOT treat this as a hard + // failure — otherwise the connection is never created (#5692). + return Response.json( + { error: "Provider validation not supported", unsupported: true }, + { status: 400 } + ); + } + return Response.json({ error: "unexpected" }, { status: 500 }); + }; + + try { + const data = await api.validateOnboardingApiKey({ provider: "lmarena", apiKey: "test-key" }); + assert.equal(data.unsupported, true); + } finally { + globalThis.fetch = originalFetch; + } +}); + test("provider onboarding API ignores non-object error JSON", async () => { const originalFetch = globalThis.fetch; globalThis.fetch = async () => Response.json(null, { status: 500 });