different-ai/openwork · error · EmailSendError

resend_rejected

resend_rejected

Error message

[${input.template}] email for ${input.recipient} failed: ${input.reason}${input.detail ? ` (${input.detail})` : ""}

What it means

sendViaResend wraps a rejection from the Resend API in EmailSendError with reason "resend_rejected". result.error is set by the Resend SDK when the API accepted the request but refused to send (invalid recipient, rejected domain, quota, etc.). The detail field carries Resend's own error message.

Source

Thrown at packages/email/src/send-email.ts:138

      template: input.template,
      recipient: input.to,
      detail: "Resend transactional email requires EMAIL_FROM and RESEND_API_KEY",
    })
  }

  try {
    const resend = new Resend(apiKey)
    const result = await resend.emails.send({
      from,
      to: input.to,
      subject: input.subject,
      replyTo: input.replyTo,
      html: input.html,
      text: input.text,
    })

    if (result.error) {
      throw new EmailSendError({
        template: input.template,
        reason: "resend_rejected",
        recipient: input.to,
        detail: result.error.message,
      })
    }
  } catch (error) {
    if (error instanceof EmailSendError) {
      throw error
    }
    const message = error instanceof Error ? error.message : "Unknown error"
    throw new EmailSendError({ template: input.template, reason: "resend_network", recipient: input.to, detail: message })
  }
}

async function sendViaNodemailer(input: {
  to: string
  subject: string

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Read the detail message in the thrown EmailSendError — it contains Resend's specific rejection reason
  2. Verify your sending domain in the Resend dashboard and use a from address on that domain
  3. Check the Resend API key is valid, active, and has send permission
  4. Confirm the recipient address is valid and within Resend's allowance (e.g. verified recipient in sandbox mode)
  5. Check Resend account limits/billing if the error indicates rate or quota issues

Example fix

// before
await sendEmail({ template: 'invite', to: 'user@example.com', from: 'me@mydomain.com' }) // domain unverified
// after — verify mydomain.com in Resend first, or use an allowed test sender
await sendEmail({ template: 'invite', to: 'user@example.com', from: 'hello@verified-mydomain.com' })
Defensive patterns

Strategy: try-catch

Validate before calling

function validateResendSend({ to, from }) {
  if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(to)) throw new Error(`Invalid recipient: ${to}`);
  if (!from.endsWith('@your-verified-domain.com')) throw new Error(`Sender domain not verified in Resend: ${from}`);
}

Try / catch

try {
  await sendEmail({ template, to, from })
} catch (e) {
  if (e instanceof EmailSendError && e.reason === 'resend_rejected') {
    console.error(`Resend rejected (${e.detail}) — check domain verification, API key, and recipient`)
  } else throw e
}

Prevention

When it happens

Trigger: Calling sendEmail (routed to the Resend provider) and Resend returns result.error — e.g. unverified sender domain, invalid 'to' address, API key lacking permission, or rate/billing limits.

Common situations: Sending from a domain not verified in Resend; using a sandbox 'onboarding@resend.dev' sender to arbitrary recipients; malformed or role-based recipient addresses; exhausted Resend plan limits; revoked or wrong-scope API key.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/b924a6be62964a3d. Report an issue: GitHub.