{"record":{"id":"6e069547a632bdfb","repo":"gitroomhq/postiz-app","slug":"the-publish-time-of-this-post-already-passed-it-c","errorCode":null,"errorMessage":"The publish time of this post already passed, it cannot be updated","messagePattern":"The publish time of this post already passed, it cannot be updated","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts","lineNumber":1007,"sourceCode":"    }\n\n    if (root.parentPostId) {\n      throw new BadRequestException(\n        'This id belongs to a comment, pass the id of the main post'\n      );\n    }\n\n    if (root.state !== 'QUEUE' && root.state !== 'DRAFT') {\n      throw new BadRequestException(\n        'Only scheduled posts that were not published yet (or drafts) can be updated'\n      );\n    }\n\n    if (\n      root.state === 'QUEUE' &&\n      dayjs.utc(root.publishDate).isBefore(dayjs.utc())\n    ) {\n      throw new BadRequestException(\n        'The publish time of this post already passed, it cannot be updated'\n      );\n    }\n\n    const integration = (root as any).integration;\n\n    let existingSettings: Record<string, any>;\n    try {\n      existingSettings = JSON.parse(root.settings || '{}');\n    } catch (err) {\n      existingSettings = {};\n    }\n\n    // Merge: only the passed keys change, everything else stays.\n    const mergedSettings = {\n      ...existingSettings,\n      ...(settings || {}),\n      __type: integration.providerIdentifier,","sourceCodeStart":989,"sourceCodeEnd":1025,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts#L989-L1025","documentation":"A QUEUE post whose publishDate is already in the past cannot be updated — the scheduler may be picking it up, so mutations are locked. Updates are only allowed for scheduled posts still in the future.","triggerScenarios":"Calling updatePost on a post with state QUEUE where dayjs.utc(root.publishDate).isBefore(dayjs.utc()) — e.g. editing a post whose slot elapsed seconds ago while the editor was open.","commonSituations":"Long-open editor sessions on soon-to-publish posts; server/client clock skew making 'future' posts appear past on the server; retries after network delays on a post that just went due.","solutions":["Refresh and check the post state — if it published, create a new post instead","If it errored and is still in QUEUE past its time, delete and reschedule with a new future date","Guard the UI: disable save when publishDate is within a few minutes of now","Verify server clock synchronization (NTP) if you suspect clock skew"],"exampleFix":"// before\nawait updatePost(orgId, postId, body); // publishDate already passed\n// after\nif (dayjs.utc(post.publishDate).isAfter(dayjs.utc())) {\n  await updatePost(orgId, postId, body);\n} else {\n  await createPost(orgId, { ...body, type: 'schedule' });\n}","handlingStrategy":"validation","validationCode":"const isFuture = dayjs.utc(post.publishDate).isAfter(dayjs.utc());\nif (post.state === 'QUEUE' && isFuture) await updatePost(orgId, postId, body);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Disable save as publishDate approaches (e.g. within 1-2 minutes)","Use server time, not client clock, for the comparison","Warn users editing posts that are about to publish"],"tags":["posts","time","scheduler","update","clock"],"backgroundTag":"stale-timestamp-guard","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}