amruthpillai/reactive-resume · error · ORPCError
BAD_REQUEST
BAD_REQUEST
Error message
Invalid AI provider configuration.
What it means
BAD_REQUEST thrown by the throwAiProviderConfigError helper in the AI router. Reached when an AI feature's catch block detects the sentinel error message 'INVALID_AI_BASE_URL' (isInvalidAiBaseUrlError), indicating the provider's configured baseURL failed normalization during the model call. Functionally the same root cause as error 25 but surfaced from the AI-feature path rather than the provider-management path.
Source
Thrown at packages/api/src/features/ai/router.ts:32
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),
});
}
async function getRunnableProvider(userId: string, aiProviderId?: string) {
const provider = aiProviderId
? await aiProvidersService.getRunnableById({ id: aiProviderId, userId })View on GitHub (pinned to 3a5b12e2a4)
Solutions
- Open the provider in Settings, correct the baseURL to a full https:// URL, and re-test.
- Run POST /ai-providers/{id}/test after fixing to confirm the base resolves.
- If no aiProviderId was passed, fix the user's default-enabled provider (getDefaultRunnable path).
- Add client-side baseURL validation when saving to prevent recurrence.
Example fix
// before baseURL saved as 'api.openai.com' // after baseURL saved as 'https://api.openai.com/v1', then re-tested
Defensive patterns
Strategy: validation
Validate before calling
function assertValidAiBase(baseURL) {
try { const u = new URL(baseURL); if (u.protocol !== 'https:' && u.protocol !== 'http:') throw 0; }
catch { throw new Error('INVALID_AI_BASE_URL'); }
} Type guard
function looksLikeValidAiBaseUrl(s) {
try { const u = new URL(s); return u.protocol.startsWith('http'); } catch { return false; }
} Try / catch
try {
await ai.parsePdf(input);
} catch (e) {
if (e.code === 'BAD_REQUEST' && /Invalid AI provider configuration/i.test(e.message)) {
routeTo('/settings/integrations');
} else throw e;
} Prevention
- Validate and re-test provider baseURL whenever it is edited.
- Keep the default provider's baseURL correct so AI features do not fail.
- Surface a 'fix provider config' link when this error appears.
When it happens
Trigger: Invoking parsePdf/analyze/etc. with an aiProviderId (or default provider) whose stored baseURL is invalid, so building the model client throws 'INVALID_AI_BASE_URL', which the handler remaps to this message.
Common situations: A provider was saved with a bad baseURL before validation tightened; the user edited baseURL to something malformed and the test step was skipped; provider migration changed the expected base path.
Related errors
- BAD_REQUEST
- BAD_REQUEST
- 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/93899dce000b9bab.
Report an issue: GitHub.