payloadcms/payload · error · APIError

error.message

Error message

error.message

What it means

Thrown when the multipart/form-data parser (`processMultipartFormdata`) returns an `error` object while processing the incoming request body. The thrown `APIError` carries the parser own message, so the exact text varies (hence the placeholder `error.message`).

Source

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

        req.json = () => Promise.resolve(data)
      } catch (error) {
        if (error instanceof SyntaxError) {
          throw new APIError('Invalid JSON', 400)
        }
        req.payload.logger.error(error)
        throw error
      }
    } else if ((bodyByteSize || hasBodyStream) && contentType?.includes('multipart/')) {
      const { error, fields, files } = await processMultipartFormdata({
        options: {
          ...(payload.config.bodyParser || {}),
          ...(payload.config.upload || {}),
        },
        request: req as Request,
      })

      if (error) {
        throw new APIError(error.message)
      }

      // Set all files on req.files for access by hooks
      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']

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Read the exact `error.message` from the API response to identify the specific limit hit (size, field count, parse error).
  2. Increase the relevant limit in `config.upload` or `config.bodyParser` if the upload is legitimately large.
  3. Reduce the file size or number of fields on the client side if the limit is intentional.
  4. Ensure the client sends a well-formed multipart body with a correct `boundary` parameter in `Content-Type`.

Example fix

// before -- default limits too small for intended uploads
upload: { limits: { fileSize: 1000000 } } // 1 MB

// after
upload: { limits: { fileSize: 50000000 } } // 50 MB
bodyParser: { sizeLimit: 52428800 }
Defensive patterns

Strategy: validation

Validate before calling

// Before sending, check file sizes against configured limits
const maxFileSize = payloadConfig.upload?.limits?.fileSize ?? Infinity
for (const f of files) {
  if (f.size > maxFileSize) {
    throw new Error(`File ${f.name} exceeds maxFileSize (${maxFileSize} bytes)`)
  }
}

Try / catch

try {
  await fetch(url, { method: 'POST', body: formData })
} catch (e) {
  if (e instanceof APIError) {
    // e.message contains the specific parser error -- address size/field/parse issue
  } else throw e
}

Prevention

When it happens

Trigger: A POST/PATCH/PUT with a `multipart/` content type where the body is malformed: missing `Content-Length` with a streaming body, malformed boundary, fields exceeding the configured `bodyParser` size limits, or upload limits (`maxFileSize`, `maxFields`) being exceeded.

Common situations: File size exceeds `upload.maxFileSize` or the multipart parser limit; number of form fields exceeds `bodyParser.fields` / `maxFields`; the multipart boundary is missing or duplicated; a streaming request with no `Content-Length` hits a buffer limit; client uses an outdated multipart encoding.

Related errors


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