{"record":{"id":"ae21b68461e6fbfb","repo":"amruthpillai/reactive-resume","slug":"precondition-failed-ae21b6","errorCode":"PRECONDITION_FAILED","errorMessage":"AI providers are unavailable because ENCRYPTION_SECRET is not configured.","messagePattern":"AI providers are unavailable because ENCRYPTION_SECRET is not configured\\.","errorType":"http","errorClass":"ORPCError","httpStatus":412,"severity":"critical","filePath":"packages/api/src/features/ai/router.ts","lineNumber":36,"sourceCode":"function 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 })\n\t\t: await aiProvidersService.getDefaultRunnable({ userId });\n\n\tif (!provider) throw new ORPCError(\"BAD_REQUEST\", { message: \"No tested AI provider is available.\" });\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/amruthpillai/reactive-resume/blob/3a5b12e2a40374a9571988701fcb75c5a1831c42/packages/api/src/features/ai/router.ts#L18-L54","documentation":"PRECONDITION_FAILED thrown by throwCredentialEncryptionUnavailable. Reached when an AI feature's catch block detects the sentinel error message 'AI_CREDENTIAL_ENCRYPTION_UNAVAILABLE' (isCredentialEncryptionUnavailable), which assertCredentialEncryptionConfigured raises when the server lacks the ENCRYPTION_SECRET needed to decrypt stored API keys. AI features cannot run because credentials cannot be read.","triggerScenarios":"Any AI feature invocation on a deployment where ENCRYPTION_SECRET is missing or empty, so decryptCredential/encryptCredential refuse to operate and the service throws the sentinel before reading any provider.","commonSituations":"Fresh deployment that did not set ENCRYPTION_SECRET; secret rotation that left the env var unset; container restart after a config change dropped the secret; the provider list itself returns a PRECONDITION_FAILED from the same root cause.","solutions":["Set ENCRYPTION_SECRET in the server environment to a stable, sufficiently random value and restart.","Keep ENCRYPTION_SECRET constant across restarts — changing it invalidates previously encrypted API keys.","Add a startup check / health probe that fails fast when ENCRYPTION_SECRET is absent.","After setting it, re-enter API keys for existing providers (if the secret changed they will be undecryptable)."],"exampleFix":"# before\n# .env has no ENCRYPTION_SECRET\n\n# after\nENCRYPTION_SECRET=$(openssl rand -hex 32)","handlingStrategy":"validation","validationCode":"function assertEncryptionSecretConfigured() {\n  if (!process.env.ENCRYPTION_SECRET) throw new Error('ENCRYPTION_SECRET missing');\n}","typeGuard":"function isEncryptionUnavailable(e) {\n  return e?.code === 'PRECONDITION_FAILED' && /ENCRYPTION_SECRET/i.test(e.message);\n}","tryCatchPattern":"try {\n  await ai.parsePdf(input);\n} catch (e) {\n  if (e?.code === 'PRECONDITION_FAILED' && /ENCRYPTION_SECRET/i.test(e.message)) {\n    showAdminNotice('Set ENCRYPTION_SECRET on the server to enable AI.');\n  } else throw e;\n}","preventionTips":["Set ENCRYPTION_SECRET in every environment before enabling AI.","Add a startup health check that fails when the secret is missing.","Keep the secret stable to avoid invalidating encrypted API keys."],"tags":["ai","encryption","env","secrets","precondition-failed","config"],"backgroundTag":null,"analyzedSha":"3a5b12e2a40374a9571988701fcb75c5a1831c42","analyzedAt":"2026-08-12T22:31:22.666Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}