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
- Ensure the request URL includes the document ID segment (e.g. `/api/posts/42`).
- If calling programmatically, set `req.routeParams = { collection: 'posts', id: '42' }`.
- If the ID is legitimately optional (e.g. a combined create/find handler), pass `optionalID: true` to `getRequestCollectionWithID`.
- Verify the client targets the correct endpoint shape (list vs single-document).
- 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
- Always include the document ID in single-document endpoint URLs.
- Use optionalID: true when a handler serves both list and single-document operations.
- Set req.routeParams.id on synthetic requests.
- Use the Local API with explicit id arguments for programmatic operations.
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
- No collection was specified
- Collection with the slug ${collectionSlug} was not found
- No global was specified
- Not Found
- Missing ID of version.
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/4478cdf410b6da37.
Report an issue: GitHub.