gitroomhq/postiz-app · error · BadBody

${handleError?.value || 'Failed to upload the video to…

Error message

${handleError?.value || 'Failed to upload the video to TikTok'}

What it means

uploadTikTokVideoBytes got a non-2xx/206 response when PUTting a video chunk to TikTok's upload endpoint. The message comes from TikTok's error payload when parseable, otherwise the generic 'Failed to upload the video to TikTok'.

Solutions

  1. Inspect the raw body attached to the BadBody — it contains TikTok's specific error code/message
  2. Ensure chunk size, Content-Range and total Content-Length match what initializeUpload negotiated
  3. Retry the whole post: a fresh upload session gets a new upload_url
  4. If error is auth-related (expired_token), refresh the TikTok token and reconnect the channel
Defensive patterns

Strategy: retry

Try / catch

catch (e) { if (e instanceof BadBody && e.code === 'tiktok-error-upload') { const detail = e.body?.toString(); /* parse TikTok error, decide retry vs surface */ } throw e; }

Prevention

When it happens

Trigger: TikTok chunk upload PUT returns 4xx/5xx: expired upload_url, wrong Content-Length/Content-Range for the chunk, auth token revoked, or rate limiting during a large multi-chunk upload.

Common situations: Long-running uploads where TikTok's upload_url expires mid-way; clock skew breaking signed URLs; retrying an already-completed upload session; network interruptions causing partial chunk writes.

Related errors


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

Appendix: source

Thrown at libraries/nestjs-libraries/src/integrations/social/tiktok.provider.ts:761

        method: 'PUT',
        headers: {
          'Content-Type': contentType,
          'Content-Length': String(contentLength),
          'Content-Range': `bytes ${start}-${end}/${videoSize}`,
        },
        body,
        // Required by undici when streaming a request body.
        duplex: 'half',
      } as any);

      if (
        upload.status !== 200 &&
        upload.status !== 201 &&
        upload.status !== 206
      ) {
        const text = await upload.text().catch(() => '{}');
        const handleError = this.handleErrors(text);
        throw new BadBody(
          'tiktok-error-upload',
          text,
          Buffer.from(text),
          handleError?.value || 'Failed to upload the video to TikTok'
        );
      }
    }
  }

  private buildTikokSourceInfoBody(
    firstPost: PostDetails<TikTokDto>,
    videoSize?: number
  ) {
    const isPhoto = !hasExtension(firstPost?.media?.[0]?.path, 'mp4');

    // TikTok photo posts only support PULL_FROM_URL, there is no FILE_UPLOAD
    // path for photos, so this branch keeps pulling from the URL.
    if (isPhoto) {

View on GitHub (pinned to 0f1647f749)