gitroomhq/postiz-app · error · BadBody
X failed to process the uploaded video${processing?.error?.m
Error message
X failed to process the uploaded video${processing?.error?.message ? `: ${processing.error.message}` : ''} What it means
waitForMediaProcessing polls X's media processing status after an upload (INIT/APPEND/FINALIZE or status check); it throws when state is 'failed' or when 7 minutes elapse without 'succeeded'.
Source
Thrown at libraries/nestjs-libraries/src/integrations/social/x.provider.ts:616
};
}>('media/upload', { command: 'STATUS', media_id: mediaId });
return status.data.processing_info;
}
// Blocking processing wait, used by the paths that still resolve everything
// inside one activity (comments, and post() for pre-v1.0.6 workflows).
private async waitForMediaProcessing(client: TwitterApi, mediaId: string) {
// X drives the pace via check_after_secs; cap on accumulated wait time
// (long videos can legitimately process for many minutes) instead of an
// attempt count, but never poll forever.
let waitedMs = 0;
const maxWaitMs = 7 * 60 * 1000;
let processing = await this.mediaProcessingStatus(client, mediaId);
while (processing && processing.state !== 'succeeded') {
if (processing.state === 'failed' || waitedMs >= maxWaitMs) {
throw new BadBody(
this.identifier,
JSON.stringify(processing),
Buffer.from('{}'),
`X failed to process the uploaded video${
processing?.error?.message ? `: ${processing.error.message}` : ''
}`
);
}
const waitMs = (processing.check_after_secs || 1) * 1000;
await timer(waitMs);
waitedMs += waitMs;
processing = await this.mediaProcessingStatus(client, mediaId);
}
}
// With ten X activities running concurrently (maxConcurrentJob), a user
// publishing several posts at the same minute can 429 on the uploadView on GitHub (pinned to 0f1647f749)
Solutions
- Shorten/compress the video and retry
- Check processing_info.error in the error body for the specific X failure reason
- Retry the post — transient transcoder delays are common near the 7-minute cap
- If it consistently times out only for one file, the file itself is the problem: re-encode it
Defensive patterns
Strategy: retry
Type guard
const isTerminalOrSlow = (state?: string, waitedMs: number) => state === 'failed' || waitedMs >= 7 * 60 * 1000;
Try / catch
catch (e) { if (e instanceof BadBody && e.message.includes('process the uploaded video')) { /* safe to retry: tweet not yet created */ } throw e; } Prevention
- Compress long videos so processing finishes well under 7 minutes
- Retry once on timeout — the post is not created yet
- Watch X's transcoder status during incidents before scheduling video posts
When it happens
Trigger: GET media/upload.json?command=STATUS keeps returning in_progress for 7 minutes, or returns state 'failed' (transcode error, too-long video, invalid media).
Common situations: Long/high-bitrate videos on busy X transcoders; rate-limited STATUS polling; media at the edge of X's limits that processes slowly then fails.
Related errors
- X failed to process the uploaded video${(processing as any)?
- X took too long to process the media, please try again
- LinkedIn ${label} processing failed${status.processingFailur
- LinkedIn took too long to process the media, please try agai
- The media took too long to process, please try again
AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27).
Data as JSON: /api/errors/1ca3cfaca2ce4bc0.
Report an issue: GitHub.