gitroomhq/postiz-app · error · BadRequestException

Only scheduled posts that were not published yet (or drafts)

Error message

Only scheduled posts that were not published yet (or drafts) can be updated

What it means

Only posts in state QUEUE (scheduled, not yet published) or DRAFT can be updated. Once a post transitions to PUBLISHED (or another terminal state) the update path refuses it, preventing edits to already-delivered content.

Source

Thrown at libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts:998

    settings: Record<string, any>,
    creationMethod: CreationMethod
  ): Promise<{ postId: string; publishDate: string }> {
    // Ordered as post -> comments, root includes integration and tags.
    const ordered = await this.getPostsRecursively(postId, true, orgId, true);

    const [root] = ordered;
    if (!root) {
      throw new NotFoundException('Post not found');
    }

    if (root.parentPostId) {
      throw new BadRequestException(
        'This id belongs to a comment, pass the id of the main post'
      );
    }

    if (root.state !== 'QUEUE' && root.state !== 'DRAFT') {
      throw new BadRequestException(
        'Only scheduled posts that were not published yet (or drafts) can be updated'
      );
    }

    if (
      root.state === 'QUEUE' &&
      dayjs.utc(root.publishDate).isBefore(dayjs.utc())
    ) {
      throw new BadRequestException(
        'The publish time of this post already passed, it cannot be updated'
      );
    }

    const integration = (root as any).integration;

    let existingSettings: Record<string, any>;
    try {
      existingSettings = JSON.parse(root.settings || '{}');

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Refresh the post state; if it is PUBLISHED, create a new post instead of updating
  2. For queue/draft posts, retry the update after confirming state via getPostById
  3. If editing published content is truly needed, clone the post and schedule it anew
  4. Subscribe to post state change events so the UI locks editing when state leaves QUEUE/DRAFT

Example fix

// before
await updatePost(orgId, postId, body);
// after
const post = await getPostById(orgId, postId);
if (post.state === 'QUEUE' || post.state === 'DRAFT') {
  await updatePost(orgId, postId, body);
} else {
  await createPost(orgId, { ...body, type: 'schedule' }); // new post
}
Defensive patterns

Strategy: validation

Validate before calling

const post = await getPostById(orgId, postId);
const editable = post?.state === 'QUEUE' || post?.state === 'DRAFT';
if (editable) await updatePost(orgId, postId, body);

Type guard

const isEditableState = (s: string): s is 'QUEUE' | 'DRAFT' => s === 'QUEUE' || s === 'DRAFT';

Prevention

When it happens

Trigger: Calling updatePost on a post whose state is PUBLISHED, ERROR, or any state other than QUEUE/DRAFT — e.g. editing a post that has just gone out while the calendar was still open.

Common situations: Race between scheduler publishing the post and the user clicking save; stale calendar state after a websocket refresh; attempting to 'edit history' of published posts via the API.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27). Data as JSON: /api/errors/9e5f3b3048f7e6bd. Report an issue: GitHub.