gitroomhq/postiz-app · error · BadBody
${handleError?.value || publish?.message || 'TikTok refused
Error message
${handleError?.value || publish?.message || 'TikTok refused the post'} What it means
postPending's final fallback: the publish envelope has code != 0 / no share_id and the error was not classified as refresh-token or disconnect, so a BadBody 'TikTok refused the post' is thrown with TikTok's message.
Source
Thrown at libraries/nestjs-libraries/src/integrations/social/tiktok.business.provider.ts:712
const asString = JSON.stringify(publish);
const handleError = this.handleErrors(asString);
if (handleError?.type === 'refresh-token') {
throw new RefreshToken(
'tiktok-business',
asString,
JSON.stringify(body),
handleError.value
);
}
if (handleError?.type === 'disconnect') {
throw new Disconnect(
'tiktok-business',
asString,
JSON.stringify(body),
handleError.value
);
}
throw new BadBody(
'tiktok-business-error-upload',
asString,
Buffer.from(JSON.stringify(body)),
handleError?.value || publish?.message || 'TikTok refused the post'
);
}
// The publish is now irreversible on TikTok's side: return `pending` so the
// workflow polls checkPostStatus instead of blocking (and possibly timing
// out and re-posting) inside this activity.
return [
{
id: firstPost.id,
releaseURL: '',
postId: '',
status: 'pending',
pendingData: { publishId: publish.data.share_id },
},View on GitHub (pinned to 0f1647f749)
Solutions
- Read the logged asString body - code/message identify the refusal reason
- Publish promptly after video upload so the video_id is still valid
- Verify the app has the scopes required for the chosen privacy level
- Check TikTok rate/quota limits
Defensive patterns
Strategy: try-catch
Validate before calling
// publish promptly after upload so video_id stays valid if (Date.now() - upload.finishedAt > 60 * 60 * 1000) await reuploadVideo();
Type guard
const isRefusedEnvelope = (p: any) => p?.code !== 0 || !p?.data?.share_id;
Try / catch
try { await provider.postPending(...); } catch (e) { if (e instanceof BadBody && /refused the post/.test(e.message)) surfaceApiReason(e.error); throw e; } Prevention
- Publish within minutes of video upload
- Verify app scopes cover the chosen privacy level
- Parse and display TikTok's code/message from the logged body
When it happens
Trigger: Business API rejects the direct post request itself: invalid video_id (expired upload), unsupported field combination, rate limit, or param validation error.
Common situations: Video uploaded but publish delayed past the video's validity window, wrong privacy option for the app's scopes, or hitting the daily post quota.
Related errors
- ${handleError?.value || information?.message || 'Could not l
- Integration not allowed
- File is too large.
- Unsupported file type.
- All media must be uploaded through our upload API route and
AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27).
Data as JSON: /api/errors/94ad28ae7bd64703.
Report an issue: GitHub.