{"record":{"id":"4a19eed0abfe7319","repo":"gitroomhq/postiz-app","slug":"x-may-have-already-published-this-post-please-che","errorCode":null,"errorMessage":"X may have already published this post, please check your account before posting again to avoid duplicates","messagePattern":"X may have already published this post, please check your account before posting again to avoid duplicates","errorType":"exception","errorClass":"BadBody","httpStatus":null,"severity":"error","filePath":"libraries/nestjs-libraries/src/integrations/social/x.provider.ts","lineNumber":832,"sourceCode":"          },\n          mediaIds: (media[firstPost.id] || []).filter((f) => f),\n          ...(coverMediaId ? { coverMediaId } : {}),\n          processingIds,\n        } as XPendingData,\n      },\n    ];\n  }\n\n  override async checkPostStatus(\n    accessToken: string,\n    pendingData: XPendingData,\n    integration: Integration\n  ): Promise<PendingCheckResponse> {\n    // A confirmed create attempt died without reporting its result: X gives\n    // no cheap way to ask whether that tweet was created, so never run the\n    // create again - stop with an explicit warning instead.\n    if (pendingData.attempting && pendingData.confirmed) {\n      throw new BadBody(\n        this.identifier,\n        '{}',\n        Buffer.from('{}'),\n        'X may have already published this post, please check your account before posting again to avoid duplicates'\n      );\n    }\n\n    const client = await this.getClient(accessToken);\n\n    // Check every media still transcoding; keep the ones not succeeded yet.\n    const stillProcessing: string[] = [];\n    for (const mediaId of pendingData.processingIds || []) {\n      let processing:\n        | { state: string; check_after_secs?: number; error?: { message?: string } }\n        | undefined;\n      try {\n        processing = await this.mediaProcessingStatus(client, mediaId);\n      } catch (err: any) {","sourceCodeStart":814,"sourceCodeEnd":850,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/libraries/nestjs-libraries/src/integrations/social/x.provider.ts#L814-L850","documentation":"checkPostStatus detects that a tweet-creation attempt was started (attempting) and the OAuth step was confirmed (confirmed) but the result was never recorded — the activity died mid-flight. X has no cheap idempotency check for tweet creation, so re-running could duplicate the post; it stops with an explicit BadBody warning instead.","triggerScenarios":"Temporal worker crash/timeout between the confirmed create call to X and persisting the result: pendingData.attempting && pendingData.confirmed are both true when the check activity resumes.","commonSituations":"Activity timeouts on slow X API responses; worker restarts or deploys during posting; network drop after X accepted the create request.","solutions":["Manually check the X account to see whether the tweet was actually published","Delete the duplicate on X if it went out, then retry or dismiss the pending post","Avoid deploying/restarting workers while posts are mid-flight","If X is timing out frequently, reduce media size to speed up the create call"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// before re-running a pending post create:\nif (pendingData.attempting && pendingData.confirmed) { /* skip auto-retry; require manual confirmation */ }","typeGuard":"const isUncertainOutcome = (p: { attempting?: boolean; confirmed?: boolean }) => Boolean(p.attempting && p.confirmed);","tryCatchPattern":"catch (e) { if (e instanceof BadBody && e.message.includes('already published')) { /* check the X account manually; delete duplicate or confirm posted */ } throw e; }","preventionTips":["Never auto-retry creates after a confirmed-in-flight attempt","Keep posting activities short so they finish before timeouts","Monitor pendingData flags in your own integrations to avoid duplicate writes"],"tags":["x-twitter","idempotency","pending-post","possible-duplicate"],"backgroundTag":"uncertain-write-outcome","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}