{"record":{"id":"20d8e52dc97c728e","repo":"unslothai/unsloth","slug":"unknown-provider-type-payload-provider-type","errorCode":null,"errorMessage":"Unknown provider type: {payload.provider_type}","messagePattern":"Unknown provider type: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"studio/backend/routes/providers.py","lineNumber":481,"sourceCode":"\n@router.post(\"/test\", response_model = ProviderTestResult)\nasync def test_provider(\n    payload: ProviderTestRequest,\n    _current_subject: str = Depends(get_current_subject),\n    via_api_key: bool = Depends(authenticated_via_api_key),\n):\n    \"\"\"\n    Test connectivity to an external provider.\n\n    Makes a lightweight GET /models call to verify the API key works. Generic\n    custom endpoints use a chat-completions probe because /models is optional.\n    An explicit encrypted key takes precedence over the saved provider key.\n    \"\"\"\n\n    payload = _bind_saved_provider_target(payload)\n    info = get_provider_info(payload.provider_type)\n    if info is None:\n        raise HTTPException(\n            status_code = 400,\n            detail = f\"Unknown provider type: {payload.provider_type}\",\n        )\n\n    api_key = resolve_provider_api_key_or_400(\n        payload.provider_id,\n        payload.encrypted_api_key,\n        allow_saved_key = not via_api_key,\n    )\n\n    base_url = payload.base_url or info[\"base_url\"]\n    if payload.provider_type == \"custom\":\n        if not base_url:\n            return ProviderTestResult(\n                success = False,\n                message = \"Connection failed: Base URL is required for custom providers.\",\n                models_count = None,\n            )","sourceCodeStart":463,"sourceCodeEnd":499,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/providers.py#L463-L499","documentation":"A 400 from the connectivity-test endpoint: after _bind_saved_provider_target resolved the payload, get_provider_info(payload.provider_type) returned None. The provider_type string (possibly inherited from a saved provider row or sent directly) is not in the provider registry, so no probe can be constructed. Note this message variant does not include the registry hint — compare with the create-endpoint variant which does.","triggerScenarios":"POST test-connectivity with a typo'd or removed provider_type; a saved provider row whose stored provider_type no longer exists in this backend version; sending provider_id of a legacy row without an explicit key so the stale stored type is used.","commonSituations":"Backend upgrades that renamed provider types while old rows persist; clients hardcoding type ids; hand-crafted test payloads.","solutions":["GET /api/providers/registry and use an exact, current provider_type id.","If a saved provider row has an obsolete type, recreate the provider with a current type (POST) and delete the stale row.","Send the payload with an explicit provider_type and encrypted_api_key to bypass stale saved config."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const registry = await fetch(\"/api/providers/registry\").then(r => r.json());\nconst valid = new Set(registry.types.map(t => t.id));\nconst effectiveType = payload.encrypted_api_key ? payload.provider_type : savedProvider?.provider_type;\nif (!valid.has(effectiveType)) throw new Error(`Unknown provider type: ${effectiveType}`);","typeGuard":null,"tryCatchPattern":"try { await testConnectivity(payload); } catch (e) { if (e.status === 400 && /Unknown provider type/i.test(e.detail)) { await refreshRegistryAndProviders(); return; } throw e; }","preventionTips":["After backend upgrades, re-fetch the registry and re-create provider rows whose stored type was renamed/removed.","When testing saved providers, remember the stored provider_type is used — verify it is still registered."],"tags":["providers","registry","connectivity","validation"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}