{"record":{"id":"7a8d53360b96497f","repo":"gitroomhq/postiz-app","slug":"handleerror-value-response-message-coul-7a8d53","errorCode":null,"errorMessage":"${handleError?.value || response?.message || 'Could not authenticate the TikTok business account'}","messagePattern":"\\$\\{handleError\\?\\.value \\|\\| response\\?\\.message \\|\\| 'Could not authenticate the TikTok business account'\\}","errorType":"exception","errorClass":"BadBody","httpStatus":null,"severity":"error","filePath":"libraries/nestjs-libraries/src/integrations/social/tiktok.business.provider.ts","lineNumber":390,"sourceCode":"          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          client_id: process.env.TIKTOK_BUSINESS_CLIENT_ID!,\n          client_secret: process.env.TIKTOK_BUSINESS_CLIENT_SECRET!,\n          grant_type: 'authorization_code',\n          auth_code: params.code,\n          redirect_uri: this.redirectUri(),\n        }),\n      })\n    ).json();\n\n    // Same HTTP 200 + non-zero code envelope as the refresh call: an expired\n    // auth_code or mismatched redirect_uri must surface TikTok's reason instead\n    // of a TypeError on the destructure.\n    if (response?.code !== 0 || !response?.data?.access_token) {\n      const asString = JSON.stringify(response);\n      const handleError = this.handleErrors(asString);\n      throw new BadBody(\n        'tiktok-business',\n        asString,\n        Buffer.from('{}'),\n        handleError?.value ||\n          response?.message ||\n          'Could not authenticate the TikTok business account'\n      );\n    }\n\n    const { access_token, refresh_token, scope, open_id } = response.data;\n\n    this.checkScopes(this.scopes, scope);\n\n    const { display_name, profile_image, username } =\n      await this.fetchUserInformation(access_token, open_id);\n\n    return {\n      id: open_id,","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/libraries/nestjs-libraries/src/integrations/social/tiktok.business.provider.ts#L372-L408","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// exchange the code exactly once, immediately after the callback\nif (state.usedCodes.has(code)) return redirectAlreadyConnected();\nstate.usedCodes.add(code);","typeGuard":null,"tryCatchPattern":"try { await provider.authenticate(code); } catch (e) { if (/authenticate the TikTok/.test(e.message)) restartOAuthFlow(); else throw e; }","preventionTips":["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"],"tags":["tiktok","oauth","auth-code","http-200-error-envelope"],"backgroundTag":"oauth-code-exchange-failed","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}