gitroomhq/postiz-app · error · BadBody

${handleError?.value || ''}

Error message

${handleError?.value || ''}

What it means

checkPostStatus sees status === 'FAILED' in the TikTok Business direct-post status body. It runs handleErrors on the reason plus full JSON and throws BadBody with the classified message (or empty string fallback), meaning TikTok definitively rejected the video.

Source

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

      // post_ids can lag up to 3 minutes behind PUBLISH_COMPLETE, and never
      // shows up at all for non-public posts - fall back to the profile URL
      // and keep the share_id (postAnalytics resolves it later).
      const publicPostId = post_ids?.[0];

      return {
        status: 'completed',
        releaseURL: !publicPostId
          ? `https://www.tiktok.com/@${integration.profile}`
          : `https://www.tiktok.com/@${integration.profile}/video/${publicPostId}`,
        postId: !publicPostId ? pendingData.publishId : String(publicPostId),
      };
    }

    if (status === 'FAILED') {
      const handleError = this.handleErrors(
        `${reason || ''} ${JSON.stringify(post)}`
      );
      throw new BadBody(
        'tiktok-business-error-upload',
        JSON.stringify(post),
        Buffer.from(JSON.stringify(post)),
        handleError?.value || ''
      );
    }

    return { status: 'pending', pendingData };
  }

  // UPLOAD does not publish - it only drops the media into the user's TikTok
  // inbox as a draft - so only an explicit UPLOAD selects it. A missing value
  // (drafts, or any caller that skipped the setting) publishes instead of
  // silently landing in the inbox.
  private contentPostingMethod(
    firstPost: PostDetails<TikTokDto>
  ): TikTokDto['content_posting_method'] {
    return firstPost?.settings?.content_posting_method === 'UPLOAD'

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Inspect the logged post JSON - the reason field names the failure cause
  2. Fix the video (codec/format/content) and re-upload
  3. If privacy=SELF_ONLY draft, ensure the post completes within the allowed window
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate video before scheduling
const probe = await ffprobe(video);
if (probe.codec !== 'h264' || probe.duration > 600) throw new Error('Video not suitable for TikTok');

Type guard

const isFailedStatus = (s?: string): s is 'FAILED' => s === 'FAILED';

Try / catch

try { await provider.check(post); } catch (e) { if (e instanceof BadBody && /tiktok-business-error-upload/.test(e.error)) markPostFailedWithReason(post, e.error); throw e; }

Prevention

When it happens

Trigger: Direct post fails TikTok's asynchronous review: policy violation, corrupted/unplayable video, privacy setting rejected, or video stuck processing then failed.

Common situations: Videos with copyrighted music, content flagged by moderation, unsupported codecs, or draft posts left beyond TikTok's processing window.

Related errors


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