{"record":{"id":"ff882b4f881d4a03","repo":"different-ai/openwork","slug":"nodemailer-rejected","errorCode":"nodemailer_rejected","errorMessage":"[${input.template}] email for ${input.recipient} failed: ${input.reason}${input.detail ? ` (${input.detail})` : \"\"}","messagePattern":"\\[(.+?)\\] email for (.+?) failed: (.+?)(.+?)\\)` : \"\"\\}","errorType":"exception","errorClass":"EmailSendError","httpStatus":null,"severity":"error","filePath":"packages/email/src/send-email.ts","lineNumber":196,"sourceCode":"      auth: smtp.user\n        ? {\n            user: smtp.user,\n            pass: smtp.pass,\n          }\n        : undefined,\n    })\n\n    await transporter.sendMail({\n      from,\n      to: input.to,\n      subject: input.subject,\n      replyTo: input.replyTo,\n      html: input.html,\n      text: input.text,\n    })\n  } catch (error) {\n    const message = error instanceof Error ? error.message : \"Unknown error\"\n    throw new EmailSendError({ template: input.template, reason: \"nodemailer_rejected\", recipient: input.to, detail: message })\n  }\n}\n","sourceCodeStart":178,"sourceCodeEnd":199,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/email/src/send-email.ts#L178-L199","documentation":"The Nodemailer SMTP transport wraps any exception thrown by transporter.sendMail in EmailSendError with reason \"nodemailer_rejected\", preserving the underlying message (SMTP error, auth failure, connection error) in detail. It means the SMTP delivery itself failed rather than an API-level rejection.","triggerScenarios":"sendEmail routed to the Nodemailer provider and transporter.sendMail throws — SMTP connection refused, bad credentials, rejected recipient, TLS failure, or timeout.","commonSituations":"Wrong SMTP host/port or missing credentials in env (SMTP_HOST/SMTP_USER/SMTP_PASS); provider blocking port 25/587 from cloud hosts; self-signed or expired TLS certificates; recipient address rejected by the mail server; rate limits on the SMTP account.","solutions":["Read detail in the thrown EmailSendError for the exact SMTP error code/message","Verify SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS env values and that the account is active","Confirm the host allows outbound traffic on the configured SMTP port (many clouds block 25; use 587 with STARTTLS)","If the error is 5xx auth/login failure, reset credentials or enable an app password","Retry for transient 4xx SMTP responses; verify the recipient address for 550-class rejections"],"exampleFix":"// before\ntransporter = nodemailer.createTransport({ host: 'smtp.gmail.com', port: 25 }) // blocked + no auth\n// after\ntransporter = nodemailer.createTransport({ host: 'smtp.gmail.com', port: 587, secure: false, auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS } })","handlingStrategy":"try-catch","validationCode":"function assertSmtpConfig(env) {\n  for (const key of ['SMTP_HOST', 'SMTP_PORT', 'SMTP_USER', 'SMTP_PASS']) {\n    if (!env[key]) throw new Error(`Missing ${key} — nodemailer sends will fail`);\n  }\n  const port = Number(env.SMTP_PORT);\n  if (port !== 587 && port !== 465) console.warn(`Unusual SMTP port ${port}; many clouds block 25`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await sendEmail({ template, to })\n} catch (e) {\n  if (e instanceof EmailSendError && e.reason === 'nodemailer_rejected') {\n    console.error(`SMTP send failed: ${e.detail}`) // inspect SMTP code in detail\n  } else throw e\n}","preventionTips":["Validate SMTP env config at startup","Use port 587 (STARTTLS) or 465 (implicit TLS), not 25","Use app passwords / credentials valid for SMTP auth","Verify recipient addresses to avoid 550 rejections","Handle transient 4xx responses with retry"],"tags":["email","smtp","nodemailer","network"],"backgroundTag":"email-send-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}