{"record":{"id":"4da17403f67e9448","repo":"payloadcms/payload","slug":"attachment-is-missing-both-content-and-path","errorCode":null,"errorMessage":"Attachment is missing both content and path","messagePattern":"Attachment is missing both content and path","errorType":"validation","errorClass":"APIError","httpStatus":400,"severity":"error","filePath":"packages/email-resend/src/index.ts","lineNumber":156,"sourceCode":"  }\n\n  return [addresses.address]\n}\n\nfunction mapAttachments(\n  attachments: SendEmailOptions['attachments'],\n): ResendSendEmailOptions['attachments'] {\n  if (!attachments) {\n    return []\n  }\n\n  return attachments.map((attachment): Attachment => {\n    if (!attachment.filename) {\n      throw new APIError('Attachment is missing filename', 400)\n    }\n\n    if (!attachment.content && !attachment.path) {\n      throw new APIError('Attachment is missing both content and path', 400)\n    }\n\n    // When both content and path are provided, content takes priority; path is ignored.\n    if (attachment.path && !attachment.content) {\n      const path = typeof attachment.path === 'string' ? attachment.path : attachment.path.href\n      return {\n        filename: attachment.filename,\n        path,\n      }\n    }\n\n    if (typeof attachment.content === 'string') {\n      return {\n        content: attachment.content,\n        filename: attachment.filename,\n      }\n    }\n","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/email-resend/src/index.ts#L138-L174","documentation":"Thrown by the Resend email provider's attachment mapper when an attachment object has a filename but neither a `content` value nor a `path`. The mapper can only forward an attachment to the Resend API if it has bytes to send, so an attachment that is filename-only is rejected as malformed input (HTTP 400). This is a client-side validation gate before the Resend HTTP call is ever made.","triggerScenarios":"Calling sendEmail with `attachments: [{ filename: 'report.pdf' }]` (no content/path), or passing an attachment built from a partial object where the file source was conditionally omitted, e.g. `attachments: [{ filename, path: maybePath }]` when `maybePath` is undefined. Also when `attachment.path` is set to an empty string or null while `attachment.content` is also absent.","commonSituations":"Building attachments dynamically from uploaded files where the upload stream/path variable is undefined; copy-pasting an attachment example that only shows filename; migrating from another provider whose API treated content as optional; passing a URL string directly as the attachment instead of wrapping it as `{ filename, path: url }`.","solutions":["Supply `path` (a file path, URL string, or URL object) OR `content` (string or Buffer) on every attachment: `attachments: [{ filename: 'x.pdf', path: '/tmp/x.pdf' }]`.","Filter out incomplete attachments before sending: `attachments.filter(a => a.filename && (a.content || a.path))`.","If loading content asynchronously, await the file read so the variable is not undefined: `content: fs.readFileSync(p)`."],"exampleFix":"// before\nattachments: [{ filename: 'invoice.pdf' }]\n\n// after (local file)\nattachments: [{ filename: 'invoice.pdf', path: '/tmp/invoice.pdf' }]\n// after (remote URL)\nattachments: [{ filename: 'invoice.pdf', path: 'https://cdn.example.com/invoice.pdf' }]\n// after (in-memory)\nattachments: [{ filename: 'invoice.pdf', content: Buffer.from(raw) }]","handlingStrategy":"validation","validationCode":"function isAttachmentComplete(a) {\n  return Boolean(a && a.filename && (a.content != null || a.path != null && a.path !== ''))\n}\nconst safe = attachments.filter(isAttachmentComplete)","typeGuard":"import type { SendEmailOptions } from 'payload'\nfunction isCompleteAttachment(a: Partial<SendEmailOptions['attachments'][number]>): a is SendEmailOptions['attachments'][number] {\n  return Boolean(a.filename && (a.content != null || (!!a.path && a.path !== '')))\n}","tryCatchPattern":"try {\n  await payload.sendEmail({ to, from, subject, attachments: safe })\n} catch (e) {\n  if (e instanceof APIError && e.message.includes('Attachment is missing both')) {\n    // surface a friendly 'attachment source missing' error to the caller\n  }\n  throw e\n}","preventionTips":["Type attachment content as `string | Buffer` and path as `string | URL` at the call site.","Filter attachments through `isAttachmentComplete` before sending.","When loading files async, await the read so the content variable is never undefined."],"tags":["email","resend","attachments","validation","input-validation"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}