payloadcms/payload · error · APIError

A file name is required.

Error message

A file name is required.

What it means

Thrown when the multipart `file` field is a string that cannot be parsed as JSON. In the staged-upload flow, the `file` field on a multipart request is expected to contain a JSON-encoded `UploadInstructions['file']` object (including filename, collectionSlug, etc.), not a plain filename string.

Source

Thrown at packages/payload/src/utilities/addDataAndFileToRequest.ts:67

      if (files) {
        req.files = files
        // Backwards compatibility: set req.file for standard upload collections
        // Guard: if multiple files share the field name "file", files.file is an array — skip
        if (files.file && !Array.isArray(files.file)) {
          req.file = files.file
        }
      }

      if (fields?._payload && typeof fields._payload === 'string') {
        req.data = JSON.parse(fields._payload)
      }

      if (!req.file && fields?.file && typeof fields?.file === 'string') {
        let uploadedFile: UploadInstructions['file']
        try {
          uploadedFile = JSON.parse(fields.file)
        } catch {
          throw new APIError('A file name is required.', 400)
        }
        const collectionSlug =
          typeof req.routeParams?.collection === 'string'
            ? req.routeParams.collection
            : uploadedFile.collectionSlug
        const uploadConfig = collectionSlug
          ? req.payload.collections[collectionSlug]?.config.upload
          : undefined

        if (!collectionSlug || !uploadConfig) {
          throw new APIError('Invalid upload collection.', 400)
        }

        req.file = await getFileFromUploadInstructions({
          collectionSlug,
          file: uploadedFile,
          req,
        })

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Send the `file` field as a JSON-encoded `UploadInstructions['file']` object, not a plain filename.
  2. If using the Payload REST API for uploads, use the SDK or follow the current docs for the exact multipart field shape.
  3. Ensure FormData appends the JSON string correctly: `formData.append('file', JSON.stringify(instructionObject))`.
  4. Upgrade the client to match the Payload version expected upload contract.

Example fix

// before
const fd = new FormData()
fd.append('file', 'photo.jpg') // plain string -> parse fails

// after
const fd = new FormData()
fd.append('file', JSON.stringify({
  filename: 'photo.jpg',
  mimeType: 'image/jpeg',
  filesize: buf.byteLength,
  collectionSlug: 'media',
}))
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the file field is a valid JSON-encoded UploadInstructions object
const fileInstruction = JSON.stringify({
  filename: file.name,
  mimeType: file.type,
  filesize: file.size,
  collectionSlug: 'media',
})
JSON.parse(fileInstruction) // round-trip validation
const fd = new FormData()
fd.append('file', fileInstruction) // JSON string, not plain filename

Type guard

const isUploadInstructionFile = (v) =>
  !!v && typeof v === 'object'
    && typeof v.filename === 'string'
    && typeof v.mimeType === 'string'
    && typeof v.filesize === 'number'
    && typeof v.collectionSlug === 'string'

Try / catch

try {
  await fetch(url, { method: 'POST', body: formData })
} catch (e) {
  if (e instanceof APIError && e.message === 'A file name is required.') {
    // fix: send JSON-encoded file instruction instead of plain string
  } else throw e
}

Prevention

When it happens

Trigger: A multipart request includes `fields.file` as a plain string (e.g. `"photo.jpg"`) instead of a JSON object, or the JSON string is malformed. The `JSON.parse(fields.file)` call inside `addDataAndFileToRequest` then throws.

Common situations: Client is using the old upload convention (plain filename string) with a Payload version that expects the new staged-upload `UploadInstructions` JSON shape; the `file` field was double-stringified or corrupted by FormData serialization; a custom client constructs the multipart payload manually and puts the wrong value in `file`.

Related errors


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/81805b60692e7e9b. Report an issue: GitHub.