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

  1. Restart the OAuth flow from scratch to get a fresh auth_code
  2. Ensure the callback only exchanges the code once
  3. 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

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

Related errors


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