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 throwAiProviderGatewayError helper in the AI feature router. It is invoked from each AI handler's catch block when the error is recognized as an AISDKError (isAiProviderGatewayError), i.e. the AI SDK itself surfaced a provider/network/runtime error during generateText. The original error is preserved as cause for server-side reporters.
Source
Thrown at packages/api/src/features/ai/router.ts:28
import { aiProvidersService } from "../ai-providers/service";
import { resumeService } from "../resume/service";
import { aiService, fileInputSchema } from "./service";
function isInvalidAiBaseUrlError(error: unknown): boolean {
return error instanceof Error && error.message === "INVALID_AI_BASE_URL";
}
function isAiProviderGatewayError(error: unknown): boolean {
return error instanceof AISDKError;
}
function isCredentialEncryptionUnavailable(error: unknown): boolean {
return error instanceof Error && error.message === "AI_CREDENTIAL_ENCRYPTION_UNAVAILABLE";
}
/** Throws a BAD_GATEWAY ORPCError, preserving the original cause for upstream error reporters. */
function throwAiProviderGatewayError(cause?: unknown): never {
throw new ORPCError("BAD_GATEWAY", { message: "Could not reach the AI provider.", cause });
}
function throwAiProviderConfigError(): never {
throw new ORPCError("BAD_REQUEST", { message: "Invalid AI provider configuration." });
}
function throwCredentialEncryptionUnavailable(): never {
throw new ORPCError("PRECONDITION_FAILED", {
message: "AI providers are unavailable because ENCRYPTION_SECRET is not configured.",
});
}
function throwResumeStructureError(error: ZodError): never {
throw new ORPCError("BAD_REQUEST", {
message: "Invalid resume data structure",
cause: flattenError(error),
});
}View on GitHub (pinned to 3a5b12e2a4)
Solutions
- Check server logs for the preserved cause (AISDKError) to identify the exact upstream status.
- Validate the API key and model id against the provider's current API.
- Retry on transient 429/5xx with backoff; for 401/403 rotate the key and retest the provider.
- Confirm the chosen model is still available and not deprecated by the provider.
Example fix
// before
provider: { provider: 'openai', model: 'gpt-4-deprecated', apiKey: 'sk-...expired' }
// after
provider: { provider: 'openai', model: 'gpt-4o', apiKey: 'sk-...valid' } Defensive patterns
Strategy: try-catch
Validate before calling
async function verifyProviderBeforeCall(provider) {
const reachable = await canReachProvider(provider.baseURL, provider.apiKey);
if (!reachable) throw new Error('provider unreachable');
} Type guard
function isAiSdkGatewayError(e) {
return e?.code === 'BAD_GATEWAY' && /Could not reach the AI provider/i.test(e.message);
} Try / catch
try {
await ai.parsePdf(input);
} catch (e) {
if (e?.code === 'BAD_GATEWAY') {
// inspect server logs for cause; retry with backoff for transient upstream errors
await backoffRetry(() => ai.parsePdf(input));
} else throw e;
} Prevention
- Keep provider test status green; re-test after key rotation.
- Use models the provider currently supports.
- Implement exponential backoff for 429/5xx upstream errors.
When it happens
Trigger: Any AI feature (parsePdf, analyze, etc.) where the underlying model call throws an instance of AISDKError — e.g. authentication error, rate limit, model not found, upstream timeout, or invalid response shape from the provider.
Common situations: Provider returns 401/403 (bad key), 429 (rate limit), 404 (wrong model id), 5xx; transient network blips; provider deprecating a model name; region restrictions on the API key.
Related errors
- BAD_GATEWAY
- An unknown error occurred while validating the merged resume
- BAD_REQUEST
- PRECONDITION_FAILED
- The model returned too much text during the provider test.
AI-assisted analysis of amruthpillai/reactive-resume@3a5b12e2a4 (2026-08-12).
Data as JSON: /api/errors/51d31fb18236a12d.
Report an issue: GitHub.