payloadcms/payload · error · ValidationError

The following fields are invalid: ${fieldPaths}

Error message

The following fields are invalid: ${fieldPaths}

What it means

Thrown by the beforeChange hook when one or more fields failed validation during a create or update. Payload runs every field's `validate` function via `traverseFields`, collects all `ValidationFieldError` entries, and throws a single `ValidationError` whose `data.errors` lists each offending field path and message. The message shown is the aggregated summary.

Source

Thrown at packages/payload/src/fields/hooks/beforeChange/index.ts:77

    fieldLabelPath: '',
    fields: (collection?.fields || global?.fields)!,
    global,
    mergeLocaleActions,
    operation,
    overrideAccess: overrideAccess!,
    parentIndexPath: '',
    parentIsLocalized: false,
    parentPath: '',
    parentSchemaPath: '',
    req,
    siblingData: data,
    siblingDoc: doc,
    siblingDocWithLocales: docWithLocales,
    skipValidation,
  })

  if (errors.length > 0) {
    throw new ValidationError(
      {
        id,
        collection: collection?.slug,
        errors,
        global: global?.slug,
        req,
      },
      req.t,
    )
  }

  for (const action of mergeLocaleActions) {
    await action()
  }

  return data
}

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Read `err.data.errors` for the exact field paths and per-field messages.
  2. Correct each flagged field's value in the submitted payload.
  3. If validation is wrong, adjust the field's `validate` or `required` config rather than disabling validation.
  4. For programmatic creates, run the same checks client-side before calling the Local/API.

Example fix

// before: missing required field
await payload.create({ collection: 'posts', data: { title: '' } })
// after
await payload.create({ collection: 'posts', data: { title: 'Hello', content: '...' } })
// read errors
try { ... } catch (e) {
  if (e?.data?.errors) console.error(e.data.errors) // [{ field: 'title', message: 'required' }]
}
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side pre-flight: run the same required/type checks before calling the API
function preflight(collection, data) {
  const errors = []
  for (const f of collection.fields) {
    if (f.required && (data[f.name] === undefined || data[f.name] === null || data[f.name] === '')) {
      errors.push({ field: f.name, message: 'This field is required.' })
    }
  }
  return errors
}
const errs = preflight(collection, payloadData)
if (errs.length) throw new Error('preflight failed: ' + JSON.stringify(errs))

Type guard

function isValidationError(err: any): err is { name: 'ValidationError'; data: { errors: { field: string; message: string }[] } } {
  return err?.name === 'ValidationError' && Array.isArray(err?.data?.errors)
}

Try / catch

try {
  await payload.create({ collection: 'posts', data })
} catch (err) {
  if (err?.name === 'ValidationError' && Array.isArray(err.data?.errors)) {
    // map err.data.errors -> [{ field, message }] for form rendering
    for (const e of err.data.errors) formErrors[e.field] = e.message
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: POST/PATCH a document missing a required field; submitting data of the wrong type (e.g. string into a number field); failing a custom `validate` function; JSON field failing schema validation; select field with a value not in `options`.

Common situations: Admin form submission with empty required inputs; API client sending incomplete payloads; conditional fields whose `admin.condition` hid them but the data still required values; localized fields missing in the active locale.

Related errors


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