payloadcms/payload · error · APIError
Join Model was not found for ${collectionConfig.slug}
Error message
Join Model was not found for ${collectionConfig.slug} What it means
Thrown when the join target collection's Mongoose model can't be resolved — neither `adapter.versions[collectionConfig.slug]` (drafts path) nor `adapter.collections[collectionConfig.slug]` exist. The collection config exists but its DB model was not built/registered by the adapter.
Source
Thrown at packages/db-mongodb/src/utilities/buildJoinAggregation.ts:295
if (!collectionConfig) {
throw new APIError(
`Collection config for ${join.field.collection.toString()} was not found`,
)
}
let JoinModel: CollectionModel | undefined
const useDrafts = (draftsEnabled || versions) && hasDraftsEnabled(collectionConfig)
if (useDrafts) {
JoinModel = adapter.versions[collectionConfig.slug]
} else {
JoinModel = adapter.collections[collectionConfig.slug]
}
if (!JoinModel) {
throw new APIError(`Join Model was not found for ${collectionConfig.slug}`)
}
const {
count,
limit: limitJoin = join.field.defaultLimit ?? 10,
page,
sort: sortJoin = join.field.defaultSort || collectionConfig.defaultSort,
where: whereJoin = {},
} = joins?.[join.joinPath] || {}
if (Array.isArray(join.field.collection)) {
throw new Error('Unreachable')
}
const fields = useDrafts
? buildVersionCollectionFields(adapter.payload.config, collectionConfig, true)
: collectionConfig.flattenedFields
View on GitHub (pinned to 00c58b35c0)
Solutions
- Await `payload.init()` fully before issuing join queries.
- Inspect startup logs for model-build errors on the named collection.
- Verify `versions`/`draftsAndPublish` config is consistent and valid.
- Restart the process to rebuild all models from scratch.
Example fix
// startup swallowed an error await payload.init() // throws clearly if a model fails to build // then issue join queries
Defensive patterns
Strategy: validation
Validate before calling
function assertJoinModel(adapter, slug) {
const m = adapter.collections[slug] || adapter.versions[slug]
if (!m) throw new Error(`No Mongoose model built for ${slug}`)
return m
} Type guard
const hasJoinModel = (adapter, slug) => Boolean(adapter.collections[slug] || adapter.versions[slug])
Try / catch
try { await payload.find({ collection, joins }) }
catch (e) { if (/Join Model was not found/.test(e.message)) await restartOrWaitInit() else throw e } Prevention
- Surface init errors rather than swallowing them.
- Await payload.init() before join queries.
- Verify versions/drafts config so the correct model branch is built.
When it happens
Trigger: The join target collection is registered in config but its Mongoose model was never constructed during adapter init (model build failed or was skipped), or a query runs before models are built.
Common situations: Init ordering/race; an earlier model-build error for that collection was swallowed; drafts/versions flag inconsistency between config and the models actually built; partial init after a thrown error.
Related errors
- ERROR: Failed to retrieve collection model with the slug "${
- Could not retrieve sanitized join config for ${collection}.
- Could not retrieve sanitized polymorphic joins config for ${
- Failed to retrieve array of joins for ${slug} in collectio $
- Collection config for ${join.field.collection.toString()} wa
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/7bc3d79c7d88737f.
Report an issue: GitHub.