payloadcms/payload · error · APIError
Orderable joins must target a single collection
Error message
Orderable joins must target a single collection
What it means
An `orderable: true` join field targets more than one collection (`collection` is an array — a polymorphic join). Ordering rows across collections requires a single target table with a shared order column, so polymorphic orderable joins are rejected.
Source
Thrown at packages/payload/src/fields/config/sanitizeJoinField.ts:63
throw new APIError('Join fields cannot be added to arrays, blocks or globals.')
}
if (!field.admin) {
field.admin = {}
}
if (typeof field.maxDepth === 'undefined') {
field.maxDepth = 1
}
const join: SanitizedJoin = {
field,
joinPath: `${joinPath ? joinPath + '.' : ''}${field.name}`,
parentIsLocalized,
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
targetField: undefined,
}
// Orderable joins must target a single collection
if (field.orderable && Array.isArray(field.collection)) {
throw new APIError('Orderable joins must target a single collection')
}
if (Array.isArray(field.collection)) {
for (const collection of field.collection) {
const sanitizedField = {
...field,
collection,
} as FlattenedJoinField
sanitizeJoinField({
config,
field: sanitizedField,
joinPath,
joins,
parentIsLocalized,
polymorphicJoins,
validateOnly: true,
})View on GitHub (pinned to 00c58b35c0)
Solutions
- Narrow the join to a single target collection (`collection: 'posts'`) if you need ordering.
- If polymorphism is required, set `orderable: false` (or omit it) and accept default ordering.
- Split into two separate orderable joins, one per collection.
Example fix
// before
{ type: 'join', name: 'items', orderable: true, collection: ['posts', 'pages'], on: 'owner' }
// after
{ type: 'join', name: 'posts', orderable: true, collection: 'posts', on: 'owner' } Defensive patterns
Strategy: validation
Validate before calling
function findOrderablePolymorphicJoins(fields) {
const bad = []
function walk(list) {
for (const f of list) {
if (f?.type === 'join' && f.orderable && Array.isArray(f.collection)) bad.push(f.name)
if (Array.isArray(f?.fields)) walk(f.fields)
}
}
walk(fields)
return bad
} Type guard
function orderableJoinTargetsSingleCollection(f: any): boolean {
return f?.type !== 'join' || !f.orderable || !Array.isArray(f.collection)
} Try / catch
try {
await payload.init({ config })
} catch (err) {
if (err?.name === 'APIError' && /Orderable joins must target a single/i.test(err?.message ?? '')) {
console.error('orderable join with multiple collections')
}
throw err
} Prevention
- Keep orderable joins single-collection; use multiple joins for polymorphism.
- Lint join fields: `orderable` + array `collection` is always invalid.
When it happens
Trigger: `{ type: 'join', name: 'x', orderable: true, collection: ['posts', 'pages'], on: 'owner' }`.
Common situations: Wanting a polymorphic join that is also manually reorderable; copy-pasting an orderable join and adding a second collection.
Related errors
- Join fields cannot be added to arrays, blocks or globals.
- Invalid join field ${field.name}. The config does not have a
- Relationship field was not found
- Could not retrieve sanitized polymorphic joins config for ${
- Not supported
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/138bf09568f9deeb.
Report an issue: GitHub.