{"record":{"id":"75d54d104e3954f9","repo":"payloadcms/payload","slug":"missing-id-of-document-to-update","errorCode":null,"errorMessage":"Missing ID of document to update.","messagePattern":"Missing ID of document to update\\.","errorType":"http","errorClass":"APIError","httpStatus":400,"severity":"error","filePath":"packages/payload/src/collections/operations/updateByID.ts","lineNumber":105,"sourceCode":"      overrideLock,\n      overwriteExistingFiles = false,\n      populate,\n      publishAllLocales,\n      req: {\n        fallbackLocale,\n        locale,\n        payload: { config },\n        payload,\n      },\n      req,\n      select: incomingSelect,\n      showHiddenFields,\n      trash = false,\n      unpublishAllLocales,\n    } = args\n\n    if (!id) {\n      throw new APIError('Missing ID of document to update.', httpStatus.BAD_REQUEST)\n    }\n\n    const { data } = args\n\n    // /////////////////////////////////////\n    // Access\n    // /////////////////////////////////////\n\n    const accessResults = !overrideAccess\n      ? await executeAccess(\n          { id, slug: collectionConfig.slug, data, req },\n          collectionConfig.access.update,\n        )\n      : true\n    const hasWherePolicy = hasWhereAccessResult(accessResults)\n\n    // /////////////////////////////////////\n    // Retrieve document","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/collections/operations/updateByID.ts#L87-L123","documentation":"Thrown by updateByID when the `id` argument is falsy. The operation cannot target a document without an identifier, so Payload rejects the call early (before access checks or DB reads) with HTTP 400. This guards the Local API `payload.update` and the PATCH/PUT REST routes `/:collection/:id`.","triggerScenarios":"Calling `payload.update({ collection, id: undefined, data })` or `payload.updateByID` without `id`; hitting `PATCH /api/posts` (missing the `:id` URL segment); passing `id: ''` or `id: null` from a route param that did not parse.","commonSituations":"A REST route or custom endpoint forwards `req.params.id` without validating it; an autosave/client sends an update before the create response returns an id; a script iterates over ids and one row is blank.","solutions":["Verify `id` is a non-empty string/number before calling `payload.update` (e.g. `if (!id) throw new Error('id required')`).","If using the REST API, ensure the request targets `/api/:collection/:id` with a real id in the URL.","For create-then-update flows, await the create result and read its `id`/`doc.id` before updating."],"exampleFix":"// before\nawait payload.update({ collection: 'posts', id: req.params.id, data })\n// after\nif (!req.params.id) throw new Error('Missing document id')\nawait payload.update({ collection: 'posts', id: req.params.id, data })","handlingStrategy":"validation","validationCode":"if (!id || (typeof id !== 'string' && typeof id !== 'number')) {\n  throw new Error('A non-empty document id is required before update.')\n}\nawait payload.update({ collection, id, data, req })","typeGuard":"function hasValidId(id: unknown): id is string | number {\n  return (typeof id === 'string' && id.length > 0) || typeof id === 'number'\n}","tryCatchPattern":"try {\n  await payload.update({ collection, id, data, req })\n} catch (err) {\n  if (err instanceof APIError && err.status === 400 && /Missing ID/.test(err.message)) {\n    // caller passed no id — fix the call site\n  }\n  throw err\n}","preventionTips":["Always type the caller's id as `string | number` (not optional) at the boundary.","Validate route params (`req.params.id`) before forwarding to payload.update.","For create-then-update flows, read `result.doc.id` from the create response first."],"tags":["collections","update","local-api","validation","rest-api"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}