{"record":{"id":"b4a1c0178f7bf245","repo":"janhq/jan","slug":"access-forbidden-check-your-api-key-permissions-f","errorCode":null,"errorMessage":"Access forbidden: Check your API key permissions for ${provider.provider}","messagePattern":"Access forbidden: Check your API key permissions for (.+?)","errorType":"exception","errorClass":null,"httpStatus":403,"severity":"error","filePath":"web-app/src/services/providers/tauri.ts","lineNumber":208,"sourceCode":"\n        lastStatus = response.status\n        lastStatusText = response.statusText\n\n        if (\n          [401, 403, 429].includes(response.status) &&\n          ki < keyAttempts.length - 1\n        ) {\n          continue\n        }\n\n        if (!response.ok) {\n          if (response.status === 401) {\n            throw new Error(\n              `Authentication failed: API key is required or invalid for ${provider.provider}`\n            )\n          }\n          if (response.status === 403) {\n            throw new Error(\n              `Access forbidden: Check your API key permissions for ${provider.provider}`\n            )\n          }\n          if (response.status === 404) {\n            throw new Error(\n              `Models endpoint not found for ${provider.provider}. Check the base URL configuration.`\n            )\n          }\n          throw new Error(\n            `Failed to fetch models from ${provider.provider}: ${response.status} ${response.statusText}`\n          )\n        }\n\n        const data = await response.json()\n\n        if (data.data && Array.isArray(data.data)) {\n          return data.data\n            .map((model: { id: string }) => model.id)","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/web-app/src/services/providers/tauri.ts#L190-L226","documentation":"Thrown when the provider's /models endpoint responds with HTTP 403. The request was authenticated (or at least not rejected as unauthenticated) but the key or origin lacks permission for this resource, or the server is blocking access (e.g. CORS/origin policy, region block, plan restrictions).","triggerScenarios":"GET `${provider.base_url}/models` returned 403 after all key attempts; typical when the key is valid but scoped without models:list permission, or the remote endpoint rejects the tauri://localhost origin.","commonSituations":"Restricted/scoped API key without model-list permission; provider blocks requests from browser/webview origins (CORS); organization policy or paid-plan gating; proxy/firewall returning 403; wrong base_url pointing at a service with different ACLs.","solutions":["Check the API key's permissions/scopes on the provider dashboard and grant model listing access.","Verify the base URL points to the correct provider API and that your plan/region allows it.","For self-hosted servers, allow the tauri://localhost origin or configure CORS/ACL rules.","Try a different (unrestricted) API key via curl to isolate key vs. network blocking."],"exampleFix":"// before: restricted key without read scope\nheaders['Authorization'] = 'Bearer sk-restricted-no-scope'\n// after: use a key with models:list permission\nheaders['Authorization'] = 'Bearer sk-<key-with-models-read>'","handlingStrategy":"try-catch","validationCode":"// Verify key permissions out-of-band before calling:\nconst res = await fetch(`${provider.base_url}/models`, { headers: { Authorization: `Bearer ${key}` } })\nif (res.status === 403) console.warn('Key lacks models:list permission')","typeGuard":null,"tryCatchPattern":"try {\n  await fetchModelsFromProvider(provider)\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Access forbidden')) {\n    showPermissionHelp(provider.provider) // guide user to key scopes/CORS\n  }\n}","preventionTips":["Use API keys with the least scopes that still include model listing.","When proxying, allow the app's origin (tauri://localhost) in CORS/ACL rules.","Check plan/region restrictions on the provider dashboard before onboarding."],"tags":["http-403","permissions","api-key","cors"],"backgroundTag":"permission-denied","analyzedSha":"7205d770c1e097c3daf35a911176410e93bc5564","analyzedAt":"2026-09-17T14:27:30.100Z","contentChangedAt":"2026-09-17T14:27:30.100Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}