payloadcms/payload · error · APIError

Collection with the slug ${collectionSlug} was not found

Error message

Collection with the slug ${collectionSlug} was not found

What it means

Thrown by `getRequestCollection` when `req.routeParams.collection` is a string but does not match any registered collection in `req.payload.collections`. This means the slug in the URL does not correspond to a collection defined in the Payload config.

Source

Thrown at packages/payload/src/utilities/getRequestEntity.ts:17

import type { Collection } from '../collections/config/types.js'
import type { SanitizedGlobalConfig } from '../globals/config/types.js'
import type { PayloadRequest } from '../types/index.js'

import { APIError } from '../errors/APIError.js'

export const getRequestCollection = (req: PayloadRequest): Collection => {
  const collectionSlug = req.routeParams?.collection

  if (typeof collectionSlug !== 'string') {
    throw new APIError(`No collection was specified`, 400)
  }

  const collection = req.payload.collections[collectionSlug]

  if (!collection) {
    throw new APIError(`Collection with the slug ${collectionSlug} was not found`, 404)
  }

  return collection
}

export const getRequestCollectionWithID = <T extends boolean>(
  req: PayloadRequest,
  {
    disableSanitize,
    optionalID,
  }: {
    disableSanitize?: T
    optionalID?: boolean
  } = {},
): {
  collection: Collection
  id: T extends true ? string : number | string
} => {

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Verify the collection slug in the request matches a collection defined in `config.collections`.
  2. Check for slug casing -- Payload collection slugs are case-sensitive.
  3. Ensure any plugin or module that registers the collection is properly imported in the config.
  4. Confirm the same config is loaded across environments (no missing plugin imports).
  5. If the collection was intentionally removed, update the client to stop referencing it.

Example fix

// before -- slug mismatch
await fetch('/api/Media') // config defines slug: 'media' (lowercase)

// after
await fetch('/api/media')
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify the collection slug is registered before making the request
const registeredSlugs = Object.keys(payload.collections)
if (!registeredSlugs.includes(requestedSlug)) {
  throw new Error(`Collection '${requestedSlug}' is not registered. Available: ${registeredSlugs.join(', ')}`)
}

Type guard

const isRegisteredCollection = (slug, collections) => slug in collections

Try / catch

try {
  await fetch(`/api/${slug}`)
} catch (e) {
  if (e instanceof APIError && e.message.includes('was not found')) {
    // check config.collections for the correct slug
  } else throw e
}

Prevention

When it happens

Trigger: A REST request targets `/api/:collection` where `:collection` is a slug that was never registered -- e.g. a typo, a deleted collection, or a slug from a different environment.

Common situations: Client hardcodes a collection slug that was renamed or removed in a config migration; an environment mismatch (staging has a collection production does not); the slug casing differs (e.g. `Media` vs `media`); a plugin that was supposed to register the collection is not loaded.

Related errors


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