{"record":{"id":"d067d10bf34460e4","repo":"nextauthjs/next-auth","slug":"forward-email-error-json-stringify-await-res-js","errorCode":null,"errorMessage":"Forward Email error: ${JSON.stringify(await res.json())}","messagePattern":"Forward Email error: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/providers/forwardemail.ts","lineNumber":31,"sourceCode":"      const { identifier: to, provider, url, theme } = params\n      const { host } = new URL(url)\n      const res = await fetch(\"https://api.forwardemail.net/v1/emails\", {\n        method: \"POST\",\n        headers: {\n          Authorization: `Basic ${btoa(provider.apiKey + \":\")}`,\n          \"Content-Type\": \"application/json\",\n        },\n        body: JSON.stringify({\n          from: provider.from,\n          to,\n          subject: `Sign in to ${host}`,\n          html: html({ url, host, theme }),\n          text: text({ url, host }),\n        }),\n      })\n\n      if (!res.ok)\n        throw new Error(\n          \"Forward Email error: \" + JSON.stringify(await res.json())\n        )\n    },\n    options: config,\n  }\n}\n","sourceCodeStart":13,"sourceCodeEnd":38,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/providers/forwardemail.ts#L13-L38","documentation":"The Forward Email provider throws this when the Forward Email HTTP API responds with a non-OK status during sendVerificationRequest. The provider intentionally includes the full JSON error body returned by the API so the developer can see exactly why the send failed (auth, domain, rate limit, etc.). It aborts the sign-in email flow, so the user never receives the verification link.","triggerScenarios":"Forward Email's POST /v1/email endpoint returns 4xx/5xx during sendVerificationRequest — e.g. invalid/missing FORWARD_EMAIL_API_KEY, unverified sending domain, malformed message, or rate limiting. Any res.ok === false triggers the throw with the API's JSON body embedded in the message.","commonSituations":"Developers hit this when the API key env var is unset or revoked, the 'from' domain is not verified in Forward Email, or during outages/rate limits. It often surfaces only at first sign-in attempt because the provider does no upfront credential validation.","solutions":["Check res/API error JSON in the message for auth errors; verify FORWARD_EMAIL_API_KEY is set and valid","Verify the sending domain in your Forward Email account matches provider.from","Retry after backoff if the body indicates rate limiting (429)","Add logging around sendVerificationRequest to capture the full response body"],"exampleFix":"// before\ndefault: {\n  type: \"email\",\n  // apiKey not configured -> API returns 401\n}\n// after\nimport ForwardEmail from \"@auth/core/providers/forwardemail\"\nproviders: [\n  ForwardEmail({\n    apiKey: process.env.FORWARD_EMAIL_API_KEY, // must be set\n    from: \"no-reply@your-verified-domain.com\",\n  })\n]","handlingStrategy":"try-catch","validationCode":"if (!process.env.FORWARD_EMAIL_API_KEY) throw new Error('FORWARD_EMAIL_API_KEY is not set')\nif (!provider.from?.includes('@')) throw new Error('ForwardEmail provider.from must be a full email address')","typeGuard":"function isForwardEmailConfigured(p: { apiKey?: string; from?: string }): p is { apiKey: string; from: string } {\n  return typeof p.apiKey === 'string' && p.apiKey.length > 0 && !!p.from?.includes('@')\n}","tryCatchPattern":"try {\n  await sendVerificationRequest(params)\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e)\n  console.error('Forward Email send failed:', msg) // msg embeds the API JSON body\n  // surface a generic 'could not send email' to the user; do not leak internals\n}","preventionTips":["Set and verify FORWARD_EMAIL_API_KEY in every environment before deploying","Verify the sending domain in your Forward Email account and keep provider.from on that domain","Log the full API error body (it is embedded in the message) to diagnose quickly","Monitor for 429s and add exponential backoff for rate limits"],"tags":["email","http-error","forwardemail","verification-email"],"backgroundTag":"email-api-http-error","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}