gitroomhq/postiz-app · error · BadBody
${handleError?.value || response?.message || 'Could not auth
Error message
${handleError?.value || response?.message || 'Could not authenticate the TikTok business account'} What it means
authenticate exchanges the OAuth auth_code for tokens. Like the other TikTok Business calls, failure arrives as HTTP 200 with code != 0 and no data.access_token; this BadBody surfaces the reason (e.g. invalid auth_code, redirect_uri mismatch) instead of a downstream TypeError.
Source
Thrown at libraries/nestjs-libraries/src/integrations/social/tiktok.business.provider.ts:390
'Content-Type': 'application/json',
},
body: JSON.stringify({
client_id: process.env.TIKTOK_BUSINESS_CLIENT_ID!,
client_secret: process.env.TIKTOK_BUSINESS_CLIENT_SECRET!,
grant_type: 'authorization_code',
auth_code: params.code,
redirect_uri: this.redirectUri(),
}),
})
).json();
// Same HTTP 200 + non-zero code envelope as the refresh call: an expired
// auth_code or mismatched redirect_uri must surface TikTok's reason instead
// of a TypeError on the destructure.
if (response?.code !== 0 || !response?.data?.access_token) {
const asString = JSON.stringify(response);
const handleError = this.handleErrors(asString);
throw new BadBody(
'tiktok-business',
asString,
Buffer.from('{}'),
handleError?.value ||
response?.message ||
'Could not authenticate the TikTok business account'
);
}
const { access_token, refresh_token, scope, open_id } = response.data;
this.checkScopes(this.scopes, scope);
const { display_name, profile_image, username } =
await this.fetchUserInformation(access_token, open_id);
return {
id: open_id,View on GitHub (pinned to 0f1647f749)
Solutions
- Restart the OAuth flow from scratch to get a fresh auth_code
- Ensure the callback only exchanges the code once
- Verify client_key/client_secret and redirect_uri match the TikTok app configuration
Defensive patterns
Strategy: try-catch
Validate before calling
// exchange the code exactly once, immediately after the callback if (state.usedCodes.has(code)) return redirectAlreadyConnected(); state.usedCodes.add(code);
Try / catch
try { await provider.authenticate(code); } catch (e) { if (/authenticate the TikTok/.test(e.message)) restartOAuthFlow(); else throw e; } Prevention
- Never exchange an auth_code twice (single-use)
- Match redirect_uri byte-for-byte with app config
- Start the exchange immediately when the callback arrives
When it happens
Trigger: auth_code already used or expired (they are single-use and short-lived), redirect_uri not matching the app config, or client_key/secret mismatch during the exchange.
Common situations: User retries/double-callbacks the OAuth redirect consuming the code twice, clock delay causing code expiry, or env config pointing at a different TikTok app than the one that initiated auth.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ${handleError?.value || information?.message || 'Could not l
- ${handleError?.value || response?.message || 'Could not refr
- Organization not found
- Integration not allowed
- Integration not allowed
AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27).
Data as JSON: /api/errors/7a8d53360b96497f.
Report an issue: GitHub.