payloadcms/payload · error · APIError
Either collection or globalSlug must be passed.
Error message
Either collection or globalSlug must be passed.
What it means
deleteVersions requires exactly one target: a collection slug or a global slug. If neither is supplied it throws an APIError. This is an internal DB-layer precondition; the framework normally guarantees one is passed.
Source
Thrown at packages/db-mongodb/src/deleteVersions.ts:36
if (globalSlug) {
const { globalConfig, Model } = getGlobal({
adapter: this,
globalSlug,
versions: true,
})
fields = buildVersionGlobalFields(this.payload.config, globalConfig, true)
VersionsModel = Model
} else if (collectionSlug) {
const { collectionConfig, Model } = getCollection({
adapter: this,
collectionSlug,
versions: true,
})
fields = buildVersionCollectionFields(this.payload.config, collectionConfig, true)
VersionsModel = Model
} else {
throw new APIError('Either collection or globalSlug must be passed.')
}
const query = await buildQuery({
adapter: this,
fields,
locale,
where,
})
const session = await getSession(this, req)
await VersionsModel.deleteMany(query, { session })
}
View on GitHub (pinned to 00c58b35c0)
Solutions
- Pass either `{ collection: 'posts', where: {...} }` or `{ globalSlug: 'header', where: {...} }` to deleteVersions.
- If calling from a hook, derive the slug from the hook context rather than passing undefined.
- Audit custom plugins/jobs that invoke the DB adapter's deleteVersions for missing args.
- Wrap the call in a guard that throws a clearer domain error before reaching the adapter.
Example fix
// before
await payload.db.deleteVersions({ where: { id: { equals: x } } })
// after
await payload.db.deleteVersions({
collection: 'posts',
where: { id: { equals: x } },
}) Defensive patterns
Strategy: validation
Validate before calling
function assertDeleteVersionsTarget(args: { collection?: string; globalSlug?: string }) {
if (!args.collection && !args.globalSlug) {
throw new Error('deleteVersions requires `collection` or `globalSlug`')
}
} Type guard
function hasDeleteTarget(args: unknown): args is { collection?: string; globalSlug?: string } {
if (typeof args !== 'object' || args === null) return false
const a = args as { collection?: unknown; globalSlug?: unknown }
return typeof a.collection === 'string' || typeof a.globalSlug === 'string'
} Prevention
- Always pass a collection or globalSlug when calling deleteVersions.
- Derive the slug from hook context rather than hardcoding.
- Wrap custom jobs that touch the adapter with an args assertion.
When it happens
Trigger: A programmatic call to payload.db.deleteVersions (or an internal versions-deletion path) invoked with an args object missing both `collection` and `globalSlug`. Reachable via custom jobs/hooks that call the adapter directly with an empty selector.
Common situations: Custom script/job that calls deleteVersions without specifying the entity; a bug in a plugin that forwards an incomplete args object.
Related errors
- Either collectionSlug or globalSlug must be provided
- Cannot provide both collectionSlug and globalSlug
- ${collectionSlug ? 'Collection' : 'Global'} not found: ${col
- Migration aborted: version._status field not found or has un
- Collection with the slug ${collectionSlug} was not found.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/65c9809304973e61.
Report an issue: GitHub.