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

  1. Pass either `{ collection: 'posts', where: {...} }` or `{ globalSlug: 'header', where: {...} }` to deleteVersions.
  2. If calling from a hook, derive the slug from the hook context rather than passing undefined.
  3. Audit custom plugins/jobs that invoke the DB adapter's deleteVersions for missing args.
  4. 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

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


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/65c9809304973e61. Report an issue: GitHub.