payloadcms/payload · error · APIError

ID was not specified

Error message

ID was not specified

What it means

Thrown by `getRequestCollectionWithID` when `req.routeParams.id` is absent or not a string and `optionalID` is not set. This guard ensures single-document routes (GET/PATCH/DELETE by ID) always receive a document identifier in the URL.

Source

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

    disableSanitize?: T
    optionalID?: boolean
  } = {},
): {
  collection: Collection
  id: T extends true ? string : number | string
} => {
  const collection = getRequestCollection(req)
  const id = req.routeParams?.id

  if (typeof id !== 'string') {
    if (optionalID) {
      return {
        id: undefined!,
        collection,
      }
    }

    throw new APIError(`ID was not specified`, 400)
  }

  if (disableSanitize === true) {
    return {
      id,
      collection,
    }
  }

  let sanitizedID: number | string = id

  // If default db ID type is a number, we should sanitize
  let shouldSanitize = Boolean(req.payload.db.defaultIDType === 'number')

  // UNLESS the customIDType for this collection is text.... then we leave it
  if (shouldSanitize && collection.customIDType === 'text') {
    shouldSanitize = false
  }

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Ensure the request URL includes the document ID segment (e.g. `/api/posts/42`).
  2. If calling programmatically, set `req.routeParams = { collection: 'posts', id: '42' }`.
  3. If the ID is legitimately optional (e.g. a combined create/find handler), pass `optionalID: true` to `getRequestCollectionWithID`.
  4. Verify the client targets the correct endpoint shape (list vs single-document).
  5. If using a custom ID type, confirm the value is a string in routeParams.

Example fix

// before
await fetch('/api/posts') // intended GET by ID, but no :id in URL

// after
await fetch('/api/posts/42')
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the ID is present in the route params before resolution
if (typeof req.routeParams?.id !== 'string') {
  throw new Error('Missing document ID in route params')
}

Type guard

const hasIdParam = (req) => typeof req.routeParams?.id === 'string'

Try / catch

try {
  const { id, collection } = getRequestCollectionWithID(req)
} catch (e) {
  if (e instanceof APIError && e.message === 'ID was not specified') {
    // add :id to the URL or pass optionalID: true if appropriate
  } else throw e
}

Prevention

When it happens

Trigger: A request reaches a single-document endpoint (e.g. `/api/:collection/:id`) but the route did not capture an `id` param, or an internal call invoked `getRequestCollectionWithID` without `optionalID: true` and no id present.

Common situations: The route pattern is missing the `:id` segment; a URL rewrite dropped the ID; the client called `/api/collection` (list endpoint) instead of `/api/collection/:id`; a custom route forwards to Payload without populating `routeParams.id`; programmatic code constructs a request object without the id param.

Related errors


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