payloadcms/payload · error · Error
Field "${field.name}" of type "${field.type}" has an empty r
Error message
Field "${field.name}" of type "${field.type}" has an empty relationTo array. At least one collection must be specified. What it means
A `relationship` or `upload` field has `relationTo` set to an empty array (`relationTo: []`). relationship/upload fields must point to at least one target collection slug; an empty array is meaningless and breaks schema generation and the admin select UI.
Source
Thrown at packages/payload/src/fields/config/sanitize.ts:254
}
// Join field sanitization
if (field.type === 'join') {
sanitizeJoinField({
config,
field,
joinPath,
joins,
orderableJoins,
parentIsLocalized,
polymorphicJoins,
})
}
// Relationship/upload validation
if (field.type === 'relationship' || field.type === 'upload') {
if (Array.isArray(field.relationTo) && field.relationTo.length === 0) {
throw new Error(
`Field "${field.name}" of type "${field.type}" has an empty relationTo array. At least one collection must be specified.`,
)
}
if (validRelationships) {
const relationships = Array.isArray(field.relationTo) ? field.relationTo : [field.relationTo]
relationships.forEach((relationship: string) => {
if (!validRelationships.includes(relationship)) {
throw new InvalidFieldRelationship(field, relationship)
}
})
}
}
// Upload isSortable default
if (field.type === 'upload') {
if (!field.admin || !('isSortable' in field.admin)) {View on GitHub (pinned to 00c58b35c0)
Solutions
- Provide at least one valid collection slug in `relationTo`.
- If the field should not exist when the list is empty, conditionally omit the whole field from the fields array.
- For upload fields, set `relationTo` to a single upload-enabled collection slug.
Example fix
// before
{ type: 'relationship', name: 'related', relationTo: [] }
// after
{ type: 'relationship', name: 'related', relationTo: ['posts'] } Defensive patterns
Strategy: validation
Validate before calling
function findEmptyRelationTo(fields) {
const bad = []
for (const f of fields) {
if ((f?.type === 'relationship' || f?.type === 'upload') && Array.isArray(f?.relationTo) && f.relationTo.length === 0) {
bad.push(f.name)
}
if (Array.isArray(f?.fields)) bad.push(...findEmptyRelationTo(f.fields))
}
return bad
} Type guard
function relationToIsNonEmpty(f: any): boolean {
if (f?.type !== 'relationship' && f?.type !== 'upload') return true
if (Array.isArray(f.relationTo)) return f.relationTo.length > 0
return typeof f.relationTo === 'string' && f.relationTo.length > 0
} Try / catch
try {
await payload.init({ config })
} catch (err) {
if (/empty relationTo/i.test(err?.message ?? '')) console.error('relationship/upload field with empty relationTo')
throw err
} Prevention
- When building `relationTo` dynamically, fall back to a default or skip the field entirely if the list is empty.
- Add a CI check that scans for `relationTo: []` in config files.
When it happens
Trigger: `{ type: 'relationship', name: 'x', relationTo: [] }` or an upload field with empty relationTo; dynamically building `relationTo` from a filtered list that ends up empty.
Common situations: Computing `relationTo` from an env/config-driven list that resolves to nothing in some environment; partial refactor leaving `relationTo: []` as a placeholder; conditional spread that omits all entries.
Related errors
- Field ${field.label} has reserved name '${fieldName}'.
- Field ${field.label} has invalid relationship '${relationshi
- Virtual field ${virtualField.name} in ${globalConfig ? `glob
- Invalid join field ${field.name}. The config does not have a
- Field "${field.name}" is either missing a field type or it d
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/65916a8cfceac51a.
Report an issue: GitHub.