amruthpillai/reactive-resume · error · ORPCError

BAD_GATEWAY

BAD_GATEWAY

Error message

Could not reach the AI provider.

What it means

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.

Source

Thrown at packages/api/src/features/ai-providers/router.ts:140

			summary: "Test saved AI provider",
			description: "Decrypts the saved API key server-side and validates the provider/model connection.",
		})
		.input(z.object({ id: z.string() }))
		.output(type<AiProviderResponse>())
		.use(aiRequestRateLimit)
		.errors({
			BAD_REQUEST: { message: "Invalid AI provider configuration.", status: 400 },
			BAD_GATEWAY: { message: "The AI provider returned an error or is unreachable.", status: 502 },
			NOT_FOUND: { message: "AI provider was not found.", status: 404 },
			PRECONDITION_FAILED: { message: "AI agent workspace is not configured.", status: 412 },
		})
		.handler(async ({ context, input }) => {
			try {
				return await aiProvidersService.test({ id: input.id, userId: context.user.id });
			} catch (error) {
				if (isInvalidAiBaseUrl(error)) throwInvalidProviderConfig();
				if (error instanceof ORPCError) throw error;
				throw new ORPCError("BAD_GATEWAY", { message: "Could not reach the AI provider." });
			}
		}),
};

View on GitHub (pinned to 3a5b12e2a4)

Solutions

  1. Open the provider's dashboard and confirm the API key is valid and has quota.
  2. Re-enter and re-save the API key, then re-test to force a fresh credential.
  3. Verify the baseURL is correct and reachable from the server (curl from the host).
  4. Check provider status pages and server outbound network/egress rules.
  5. Inspect server logs for the original (un-remapped) error cause to pinpoint auth vs network vs 5xx.

Example fix

// before
// provider saved with old key
{ provider: 'openai', baseURL: 'https://api.openai.com/v1', apiKey: 'sk-...revoked' }

// after
// rotate key, save, then re-test
{ provider: 'openai', baseURL: 'https://api.openai.com/v1', apiKey: 'sk-...valid' }
Defensive patterns

Strategy: retry

Validate before calling

async function canReachProvider(baseURL, apiKey) {
  try {
    const res = await fetch(baseURL + '/models', { headers: { Authorization: `Bearer ${apiKey}` } });
    return res.ok || res.status === 401; // 401 means reachable, just auth
  } catch { return false; }
}

Type guard

function isProviderUnreachableError(e) {
  return e?.code === 'BAD_GATEWAY' && /Could not reach the AI provider/i.test(e.message);
}

Try / catch

try {
  await testProvider({ id });
} catch (e) {
  if (e?.code === 'BAD_GATEWAY') {
    showToast('Cannot reach the provider. Check the key, baseURL, and network.');
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of amruthpillai/reactive-resume@3a5b12e2a4 (2026-08-12). Data as JSON: /api/errors/dc955cd1c73228e9. Report an issue: GitHub.