{"record":{"id":"93899dce000b9bab","repo":"amruthpillai/reactive-resume","slug":"bad-request-93899d","errorCode":"BAD_REQUEST","errorMessage":"Invalid AI provider configuration.","messagePattern":"Invalid AI provider configuration\\.","errorType":"http","errorClass":"ORPCError","httpStatus":400,"severity":"error","filePath":"packages/api/src/features/ai/router.ts","lineNumber":32,"sourceCode":"function isInvalidAiBaseUrlError(error: unknown): boolean {\n\treturn error instanceof Error && error.message === \"INVALID_AI_BASE_URL\";\n}\n\nfunction isAiProviderGatewayError(error: unknown): boolean {\n\treturn error instanceof AISDKError;\n}\n\nfunction isCredentialEncryptionUnavailable(error: unknown): boolean {\n\treturn error instanceof Error && error.message === \"AI_CREDENTIAL_ENCRYPTION_UNAVAILABLE\";\n}\n\n/** Throws a BAD_GATEWAY ORPCError, preserving the original cause for upstream error reporters. */\nfunction throwAiProviderGatewayError(cause?: unknown): never {\n\tthrow new ORPCError(\"BAD_GATEWAY\", { message: \"Could not reach the AI provider.\", cause });\n}\n\nfunction throwAiProviderConfigError(): never {\n\tthrow new ORPCError(\"BAD_REQUEST\", { message: \"Invalid AI provider configuration.\" });\n}\n\nfunction throwCredentialEncryptionUnavailable(): never {\n\tthrow new ORPCError(\"PRECONDITION_FAILED\", {\n\t\tmessage: \"AI providers are unavailable because ENCRYPTION_SECRET is not configured.\",\n\t});\n}\n\nfunction throwResumeStructureError(error: ZodError): never {\n\tthrow new ORPCError(\"BAD_REQUEST\", {\n\t\tmessage: \"Invalid resume data structure\",\n\t\tcause: flattenError(error),\n\t});\n}\n\nasync function getRunnableProvider(userId: string, aiProviderId?: string) {\n\tconst provider = aiProviderId\n\t\t? await aiProvidersService.getRunnableById({ id: aiProviderId, userId })","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/amruthpillai/reactive-resume/blob/3a5b12e2a40374a9571988701fcb75c5a1831c42/packages/api/src/features/ai/router.ts#L14-L50","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbaseURL saved as 'api.openai.com'\n\n// after\nbaseURL saved as 'https://api.openai.com/v1', then re-tested","handlingStrategy":"validation","validationCode":"function assertValidAiBase(baseURL) {\n  try { const u = new URL(baseURL); if (u.protocol !== 'https:' && u.protocol !== 'http:') throw 0; }\n  catch { throw new Error('INVALID_AI_BASE_URL'); }\n}","typeGuard":"function looksLikeValidAiBaseUrl(s) {\n  try { const u = new URL(s); return u.protocol.startsWith('http'); } catch { return false; }\n}","tryCatchPattern":"try {\n  await ai.parsePdf(input);\n} catch (e) {\n  if (e.code === 'BAD_REQUEST' && /Invalid AI provider configuration/i.test(e.message)) {\n    routeTo('/settings/integrations');\n  } else throw e;\n}","preventionTips":["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."],"tags":["ai","base-url","config","validation","bad-request"],"backgroundTag":null,"analyzedSha":"3a5b12e2a40374a9571988701fcb75c5a1831c42","analyzedAt":"2026-08-12T22:31:22.666Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}