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
- Read `err.data.errors` for the exact field paths and per-field messages.
- Correct each flagged field's value in the submitted payload.
- If validation is wrong, adjust the field's `validate` or `required` config rather than disabling validation.
- 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
- Mirror required/type rules on the client and pre-validate before submit.
- In custom `validate` functions, return clear messages and stable field paths.
- Use `admin.condition` carefully — hidden required fields still validate unless you also relax `required`.
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
- field must be specified
- Missing 'where' query of documents to update.
- Missing ID of document to update.
- Network response was not ok
- Not Found
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/47bb5e83dd4c90e9.
Report an issue: GitHub.