yikart/AiToEarn · error · TwitterPlatformException

ChannelPlatformMediaProcessingTimeout

ChannelPlatformMediaProcessingTimeout

Error message

ChannelPlatformMediaProcessingTimeout

What it means

Twitter media uploads go through an asynchronous processing pipeline (INIT/APPEND/FINALIZE then poll GET /2/media/upload). waitForProcessing polls the processing_info status until the media reaches a succeeded state; if the retry budget is exhausted while the media is still pending/failed, it throws TwitterPlatformException with code ChannelPlatformMediaProcessingTimeout.

Source

Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/twitter/twitter-publish.provider.ts:264

      }

      const waitMs = (info.checkAfterSecs ?? info.check_after_secs ?? 5) * 1000
      await new Promise(resolve => setTimeout(resolve, waitMs))

      const status = await this.twitterService.getMediaStatus(accessToken, mediaId)
      const statusInfo = status.processingInfo ?? {}

      if (statusInfo.state === TwitterMediaProcessingState.Succeeded)
        return
      if (statusInfo.state === TwitterMediaProcessingState.Failed) {
        throw this.mediaProcessingException('Twitter media processing failed', mediaId)
      }

      info = statusInfo
      attempt++
    }

    throw new TwitterPlatformException({
      code: ResponseCode.ChannelPlatformMediaProcessingTimeout,
      category: PlatformErrorCategory.MediaProcessingFailed,
      context: { endpoint: 'GET /2/media/upload', metadata: { mediaId } },
      cause: {
        type: PlatformErrorCauseType.Platform,
        platformMessage: 'Twitter media processing timeout',
      },
      retryable: true,
    })
  }

  private mediaProcessingException(message: string, mediaId: string): TwitterPlatformException {
    return new TwitterPlatformException({
      code: ResponseCode.ChannelPlatformMediaProcessingFailed,
      category: PlatformErrorCategory.MediaProcessingFailed,
      context: { endpoint: 'GET /2/media/upload', metadata: { mediaId } },
      cause: {
        type: PlatformErrorCauseType.Platform,

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Increase the polling attempt count / interval in waitForProcessing before giving up
  2. Verify the uploaded media conforms to Twitter media specs (size, duration, format)
  3. Retry uploadMedia once; transient processing delays are common
  4. Fall back to image-only or smaller video variants for the post

Example fix

// before
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) { ... }
// after
const MAX_ATTEMPTS = 60 // raise budget for video uploads
const POLL_INTERVAL_MS = 2000
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) { ... }
Defensive patterns

Strategy: retry

Validate before calling

const canUpload = (media: { size: number; type: string }) =>
  media.size <= 512 * 1024 * 1024 && ['video/mp4', 'image/jpeg', 'image/png', 'image/gif'].includes(media.type)

Type guard

function isProcessingSucceeded(info?: { state?: string }): boolean {
  return info?.state === 'succeeded'
}

Try / catch

try {
  await provider.uploadMedia(...)
} catch (e) {
  if (e?.code === 'ChannelPlatformMediaProcessingTimeout') {
    await sleep(5000)
    await provider.uploadMedia(...) // one retry
  } else throw e
}

Prevention

When it happens

Trigger: Calling uploadMedia with a large video (or many concurrent uploads) whose processing_info stays in 'pending'/'in_progress' past the polling attempt limit, or the platform returns 'failed' state that the poll loop treats as timeout.

Common situations: Publishing long/high-resolution videos, uploading during Twitter API latency or degraded processing, too-short polling budget configured for video assets.

Understand the failure class

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/5a6c1bc7aa671d34. Report an issue: GitHub.