{"record":{"id":"b867cae32d62004b","repo":"nextauthjs/next-auth","slug":"missing-postmark-api-key","errorCode":null,"errorMessage":"Missing Postmark API Key","messagePattern":"Missing Postmark API Key","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/providers/postmark.ts","lineNumber":15,"sourceCode":"import type { EmailConfig, EmailUserConfig } from \"./index.js\"\nimport { html, text } from \"../lib/utils/email.js\"\n\n/** @todo Document this */\nexport default function Postmark(config: EmailUserConfig): EmailConfig {\n  return {\n    id: \"postmark\",\n    type: \"email\",\n    name: \"Postmark\",\n    from: \"Auth.js <no-reply@authjs.dev>\",\n    maxAge: 24 * 60 * 60,\n    async sendVerificationRequest(params) {\n      const { identifier: to, provider, url, theme } = params\n      const { host } = new URL(url)\n      if (!provider.apiKey) throw new TypeError(\"Missing Postmark API Key\")\n      const res = await fetch(\"https://api.postmarkapp.com/email\", {\n        method: \"POST\",\n        headers: {\n          Accept: \"application/json\",\n          \"Content-Type\": \"application/json\",\n          \"X-Postmark-Server-Token\": provider.apiKey,\n        },\n        body: JSON.stringify({\n          From: provider.from,\n          To: to,\n          Subject: `Sign in to ${host}`,\n          TextBody: text({ url, host }),\n          HtmlBody: html({ url, host, theme }),\n          MessageStream: \"outbound\",\n        }),\n      })\n\n      if (!res.ok)","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/providers/postmark.ts#L1-L33","documentation":"The Postmark provider throws a TypeError when provider.apiKey is falsy before calling Postmark's API, since the X-Postmark-Server-Token header is mandatory. Like other provider guards, this fails fast as a configuration error instead of producing an obscure 401 from the API. No network request is made when this fires.","triggerScenarios":"sendVerificationRequest runs with a Postmark provider config where apiKey is undefined/null/empty — e.g. process.env.POSTMARK_API_KEY unset in the deployment environment or the option key misspelled — hitting `if (!provider.apiKey)` immediately.","commonSituations":"Deploying to an environment where POSTMARK_API_KEY was never set (works locally via .env, fails in prod); rotating the Postmark server token and forgetting to update the env var; passing the token under the wrong config key.","solutions":["Set apiKey: process.env.POSTMARK_API_KEY and ensure the env var exists in all environments","Confirm the value is a Postmark *Server* token (starts with a UUID-like string), not an account-level token","Restart/redeploy after adding the env var so the process picks it up","Add a startup check that required email env vars are present before serving traffic"],"exampleFix":"// before\nPostmark({ from: \"no-reply@example.com\" }) // apiKey missing -> TypeError\n// after\nPostmark({\n  apiKey: process.env.POSTMARK_API_KEY,\n  from: \"no-reply@example.com\",\n})","handlingStrategy":"validation","validationCode":"if (!process.env.POSTMARK_API_KEY) throw new Error('POSTMARK_API_KEY is required')\nif (!/^[0-9a-f-]{36}$/.test(process.env.POSTMARK_API_KEY)) console.warn('POSTMARK_API_KEY does not look like a Postmark server token')","typeGuard":"function isPostmarkConfigured(p: { apiKey?: string }): p is { apiKey: string } {\n  return typeof p.apiKey === 'string' && p.apiKey.length > 0\n}","tryCatchPattern":"try {\n  await sendVerificationRequest(params)\n} catch (e) {\n  if (e instanceof TypeError && e.message === 'Missing Postmark API Key') {\n    console.error('Postmark provider misconfigured: set apiKey (server token) via POSTMARK_API_KEY')\n  }\n}","preventionTips":["Set POSTMARK_API_KEY in all environments; redeploy/restart after adding it","Use a Server token (not an Account token) from the correct Postmark server","Check required env vars at startup with a config validation step","After rotating tokens, update every environment and verify with a test sign-in"],"tags":["config","email","postmark","missing-api-key","typeerror"],"backgroundTag":"missing-env-var","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}