{"record":{"id":"180be1c87688a239","repo":"gitroomhq/postiz-app","slug":"handleerror-value-response-message-coul","errorCode":null,"errorMessage":"${handleError?.value || response?.message || 'Could not refresh the TikTok access token'}","messagePattern":"\\$\\{handleError\\?\\.value \\|\\| response\\?\\.message \\|\\| 'Could not refresh the TikTok access token'\\}","errorType":"exception","errorClass":"BadBody","httpStatus":null,"severity":"error","filePath":"libraries/nestjs-libraries/src/integrations/social/tiktok.business.provider.ts","lineNumber":318,"sourceCode":"        method: 'POST',\n        headers: {\n          '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: 'refresh_token',\n          refresh_token: refreshToken,\n        }),\n      })\n    ).json();\n\n    // OAuth failures also arrive as HTTP 200 with a non-zero code and no data -\n    // without this check the destructure below throws an unclassified TypeError.\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 refresh the TikTok access token'\n      );\n    }\n\n    const { access_token, refresh_token, open_id } = response.data;\n\n    const { display_name, profile_image, username } =\n      await this.fetchUserInformation(access_token, open_id);\n\n    return {\n      refreshToken: refresh_token,\n      expiresIn: dayjs().add(23, 'hours').unix() - dayjs().unix(),\n      accessToken: access_token,","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/libraries/nestjs-libraries/src/integrations/social/tiktok.business.provider.ts#L300-L336","documentation":"refreshToken exchanges a refresh_token at TikTok's OAuth endpoint. TikTok signals OAuth failure with HTTP 200 and a non-zero code (and no data.access_token), so this BadBody surfaces TikTok's reason rather than a TypeError from destructuring an undefined token.","triggerScenarios":"refresh_token expired or revoked (user disconnected the app), client_secret mismatch, or grant_type/redirect_uri parameters wrong for the Business API.","commonSituations":"Long-unused channels whose refresh token passed TikTok's 365-day limit, rotated client secrets not updated in env config, or redirect_uri differing from the registered one.","solutions":["Verify client_key/client_secret env values match the TikTok app","Ask the user to reconnect the channel if the refresh token was revoked/expired","Compare redirect_uri against the app's registered URL exactly","Log the full response JSON to see TikTok's specific code/message"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await refreshToken(channel); } catch (e) { if (/refresh the TikTok access token/.test(e.message)) markChannelForReconnect(channel.id); throw e; }","preventionTips":["Refresh tokens on a schedule before they age out","Keep client_secret in sync with the TikTok app after rotation","Surface reconnect prompts early when refresh fails once"],"tags":["tiktok","oauth","refresh-token","http-200-error-envelope"],"backgroundTag":"refresh-token-invalid","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}