{"record":{"id":"6f0a116f48c1e2b7","repo":"payloadcms/payload","slug":"failed-to-sync-document-with-id-data-id-to-s","errorCode":null,"errorMessage":"Failed to sync document with ID: '${data.id}' to Stripe: ${msg}","messagePattern":"Failed to sync document with ID: '(.+?)' to Stripe: (.+?)","errorType":"http","errorClass":"APIError","httpStatus":500,"severity":"error","filePath":"packages/plugin-stripe/src/hooks/syncExistingWithStripe.ts","lineNumber":82,"sourceCode":"          try {\n            // api version can only be the latest, stripe recommends ts ignoring it\n            const stripe = new Stripe(pluginConfig?.stripeSecretKey || '', {\n              apiVersion: '2022-08-01',\n            })\n\n            const stripeResource = await stripe?.[syncConfig?.stripeResourceType]?.update(\n              data.stripeID,\n              syncedFields,\n            )\n\n            if (logs) {\n              payload.logger.info(\n                `✅ Successfully synced Stripe resource with ID: '${stripeResource.id}'.`,\n              )\n            }\n          } catch (error: unknown) {\n            const msg = error instanceof Error ? error.message : error\n            throw new APIError(`Failed to sync document with ID: '${data.id}' to Stripe: ${msg}`)\n          }\n        }\n      }\n    }\n  }\n\n  // Set back to 'false' so that all changes continue to sync to Stripe, see note in './createNewInStripe.ts'\n  data.skipSync = false\n\n  return data\n}\n","sourceCodeStart":64,"sourceCodeEnd":94,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/plugin-stripe/src/hooks/syncExistingWithStripe.ts#L64-L94","documentation":"Thrown by the Stripe plugin's `syncExistingWithStripe` hook when `stripe.[stripeResourceType].update(stripeID, syncedFields)` rejects while pushing local edits to an already-linked Stripe resource. The Stripe SDK error is appended as `${msg}`.","triggerScenarios":"Updating a Payload document that has a `stripeID` with field values Stripe rejects (invalid email format, disallowed metadata key, immutable field); `stripeSecretKey` invalid; the linked `stripeID` no longer exists in Stripe and the update call 404s.","commonSituations":"Stripe resource was deleted directly in the Stripe dashboard but the Payload doc still references it; field mapping changed and now produces an invalid update payload; API version drift on the pinned `2022-08-01`; rate limiting during bulk re-syncs.","solutions":["Read the `${msg}` suffix — it identifies whether it is auth, not-found, or a validation error from Stripe","If the Stripe resource no longer exists, clear `stripeID` on the Payload doc or recreate the Stripe resource","Validate the `syncConfig.fields` mapping against the current Stripe update schema for that resource","Confirm `stripeSecretKey` is correct for the account that owns the `stripeID`"],"exampleFix":"// before — stripeID points to a deleted resource\nawait payload.update({ collection: 'users', id, data: { email } })\n// after — clear stale link, let createNewInStripe recreate\nawait payload.update({ collection: 'users', id, data: { email, stripeID: null } })","handlingStrategy":"try-catch","validationCode":"// Before updating, verify the linked Stripe resource still exists\ntry {\n  await stripe.[syncConfig.stripeResourceType].retrieve(doc.stripeID)\n} catch {\n  // clear stale link, let createNewInStripe recreate on next save\n  await payload.update({ collection, id, data: { stripeID: null } })\n}","typeGuard":"import { APIError } from 'payload'\nfunction isStripeSyncError(e: unknown): e is APIError {\n  return e instanceof APIError && /^Failed to sync document with ID: .* to Stripe:/.test(e.message)\n}","tryCatchPattern":"import { APIError } from 'payload'\ntry {\n  await payload.update({ collection, id, data })\n} catch (e) {\n  if (e instanceof APIError && /Failed to sync document with ID: .* to Stripe/.test(e.message)) {\n    // suffix names the Stripe cause; if 'resource_missing', clear stripeID and retry\n  }\n  throw e\n}","preventionTips":["Keep `stripeSecretKey` current and matching the account that owns the linked resources","When a Stripe resource is deleted out-of-band, null out the Payload `stripeID` promptly","Validate `syncConfig.fields` mappings against the current Stripe update schema for that resource"],"tags":["stripe","update","sync","configuration"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}