{"record":{"id":"dc955cd1c73228e9","repo":"amruthpillai/reactive-resume","slug":"bad-gateway","errorCode":"BAD_GATEWAY","errorMessage":"Could not reach the AI provider.","messagePattern":"Could not reach the AI provider\\.","errorType":"http","errorClass":"ORPCError","httpStatus":502,"severity":"error","filePath":"packages/api/src/features/ai-providers/router.ts","lineNumber":140,"sourceCode":"\t\t\tsummary: \"Test saved AI provider\",\n\t\t\tdescription: \"Decrypts the saved API key server-side and validates the provider/model connection.\",\n\t\t})\n\t\t.input(z.object({ id: z.string() }))\n\t\t.output(type<AiProviderResponse>())\n\t\t.use(aiRequestRateLimit)\n\t\t.errors({\n\t\t\tBAD_REQUEST: { message: \"Invalid AI provider configuration.\", status: 400 },\n\t\t\tBAD_GATEWAY: { message: \"The AI provider returned an error or is unreachable.\", status: 502 },\n\t\t\tNOT_FOUND: { message: \"AI provider was not found.\", status: 404 },\n\t\t\tPRECONDITION_FAILED: { message: \"AI agent workspace is not configured.\", status: 412 },\n\t\t})\n\t\t.handler(async ({ context, input }) => {\n\t\t\ttry {\n\t\t\t\treturn await aiProvidersService.test({ id: input.id, userId: context.user.id });\n\t\t\t} catch (error) {\n\t\t\t\tif (isInvalidAiBaseUrl(error)) throwInvalidProviderConfig();\n\t\t\t\tif (error instanceof ORPCError) throw error;\n\t\t\t\tthrow new ORPCError(\"BAD_GATEWAY\", { message: \"Could not reach the AI provider.\" });\n\t\t\t}\n\t\t}),\n};\n","sourceCodeStart":122,"sourceCodeEnd":144,"githubUrl":"https://github.com/amruthpillai/reactive-resume/blob/3a5b12e2a40374a9571988701fcb75c5a1831c42/packages/api/src/features/ai-providers/router.ts#L122-L144","documentation":"BAD_GATEWAY thrown by the test handler's catch-all when aiProvidersService.test rejects with an error that is neither the 'INVALID_AI_BASE_URL' sentinel nor an ORPCError. It represents any upstream/AI-provider-side failure during the connectivity test (network, auth, 5xx, malformed response). The original cause is not attached, so only the generic message surfaces.","triggerScenarios":"POST /ai-providers/{id}/test where the saved provider's endpoint is unreachable, returns a non-2xx (auth failure, quota, 5xx), times out, or the AI SDK throws a non-sentinel error. Anything not remapped to INVALID base URL or rethrown as ORPCError lands here.","commonSituations":"Expired or revoked API key stored against the provider; wrong baseURL after a provider migration; firewall/proxy blocking outbound HTTPS; provider rate-limiting or outage; DNS failure for the provider host.","solutions":["Open the provider's dashboard and confirm the API key is valid and has quota.","Re-enter and re-save the API key, then re-test to force a fresh credential.","Verify the baseURL is correct and reachable from the server (curl from the host).","Check provider status pages and server outbound network/egress rules.","Inspect server logs for the original (un-remapped) error cause to pinpoint auth vs network vs 5xx."],"exampleFix":"// before\n// provider saved with old key\n{ provider: 'openai', baseURL: 'https://api.openai.com/v1', apiKey: 'sk-...revoked' }\n\n// after\n// rotate key, save, then re-test\n{ provider: 'openai', baseURL: 'https://api.openai.com/v1', apiKey: 'sk-...valid' }","handlingStrategy":"retry","validationCode":"async function canReachProvider(baseURL, apiKey) {\n  try {\n    const res = await fetch(baseURL + '/models', { headers: { Authorization: `Bearer ${apiKey}` } });\n    return res.ok || res.status === 401; // 401 means reachable, just auth\n  } catch { return false; }\n}","typeGuard":"function isProviderUnreachableError(e) {\n  return e?.code === 'BAD_GATEWAY' && /Could not reach the AI provider/i.test(e.message);\n}","tryCatchPattern":"try {\n  await testProvider({ id });\n} catch (e) {\n  if (e?.code === 'BAD_GATEWAY') {\n    showToast('Cannot reach the provider. Check the key, baseURL, and network.');\n  } else throw e;\n}","preventionTips":["Confirm outbound HTTPS from the server to the provider is allowed.","Rotate and re-enter the API key if a test suddenly starts failing.","Monitor provider status pages during incidents."],"tags":["ai-providers","network","upstream","test","bad-gateway"],"backgroundTag":null,"analyzedSha":"3a5b12e2a40374a9571988701fcb75c5a1831c42","analyzedAt":"2026-08-12T22:31:22.666Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}