{"record":{"id":"f2251cc5b99b2587","repo":"yikart/AiToEarn","slug":"error-response-data-error-message-f2251c","errorCode":null,"errorMessage":"初始化视频上传失败: ${error.response?.data?.error?.message || error.message}","messagePattern":"初始化视频上传失败: (.+?)","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"project/aitoearn-electron/server/src/modules/plat/tiktok/tiktok.service.ts","lineNumber":146,"sourceCode":"          video_size: videoSize,\n          chunk_size: chunkSize,\n          total_chunk_count: totalChunkCount\n        };\n      }\n\n      const { data } = await firstValueFrom(\n        this.httpService.post(`${this.apiBaseUrl}/v2/post/publish/inbox/video/init/`, requestBody, {\n          headers: {\n            'Content-Type': 'application/json',\n            'Authorization': `Bearer ${accessToken}`\n          }\n        })\n      );\n\n      return data.data;\n    } catch (error) {\n      this.logger.error('初始化TikTok视频上传失败:', error.response?.data || error.message);\n      throw new BadRequestException(`初始化视频上传失败: ${error.response?.data?.error?.message || error.message}`);\n    }\n  }\n  \n  /**\n   * 方式2：初始化视频发布（直接发布，新版）\n   * @param accessToken 访问令牌\n   * @param videoSize 视频文件总大小（字节）\n   * @param videoInfo 视频相关信息，包含标题、隐私级别等\n   * @param chunkSize 分片大小（字节），默认为10MB\n   * @returns 初始化结果，包含上传所需的参数\n   */\n  async initVideoPublish(\n    accessToken: string,\n    videoSize: number,\n    videoInfo: {\n      title?: string;\n      description?: string;\n      privacyStatus?: string;","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/modules/plat/tiktok/tiktok.service.ts#L128-L164","documentation":"This BadRequestException is thrown by TikTokService.initVideoUpload when the POST to TikTok's /v2/post/publish/inbox/video/init/ endpoint fails (network/HTTP error) or returns an error payload. The service catches any axios error from firstValueFrom, logs error.response?.data, and rethrows as a NestJS BadRequestException with the TikTok API's error.message (or the axios error message) interpolated into the Chinese message '初始化视频上传失败'. It wraps the upstream TikTok Content Posting API rejection, so the inner text usually carries TikTok's own error code/message.","triggerScenarios":"Any failed firstValueFrom(this.httpService.post(`${apiBaseUrl}/v2/post/publish/inbox/video/init/`, ...)) call: (1) TikTok returns 4xx/5xx (invalid/expired access_token, insufficient scopes like video.upload/video.publish, source_info invalid — e.g. video_size not matching actual file, chunk_size out of allowed range, total_chunk_count mismatch); (2) network timeout/DNS failure to open.tiktokapis.com so error.response is undefined and error.message is used; (3) response body shape unexpected causing downstream code to fail before return.","commonSituations":"Developers hit this when the access token was refreshed/rotated server-side but an old token is passed in, when the TikTok app lacks the video.upload or video.publish audit-approved scope (sandbox apps can only upload to private/inbox), when videoSize passed in bytes doesn't match the actual file so TikTok rejects source_info, when chunkSize is outside TikTok's allowed 5MB–64MB bounds, or when sandbox-mode apps call the production endpoint.","solutions":["Inspect this.logger.error output ('初始化TikTok视频上传失败') for error.response.data.error.code/message to get TikTok's exact error code and fix the corresponding request field.","Verify the accessToken is valid and unexpired; if invalid_token, re-run the OAuth flow via TikTokAuthService and retry with a fresh token.","Confirm the app's scopes include video.upload (inbox upload) and that the app passed TikTok's audit for production; sandbox apps cannot publish publicly.","Check source_info values: video_size must equal the actual byte size of the file, chunk_size within TikTok's allowed range (e.g. >=5MB and <=64MB), total_chunk_count = ceil(video_size/chunk_size) and > 0 (videoSize is falsy for 0-byte files so source_info is omitted).","On network-level failures (no error.response), check connectivity/proxy to open.tiktokapis.com and add timeout/retry handling in HttpService config."],"exampleFix":"// before: error surfaced only as generic BadRequestException\nthrow new BadRequestException(`初始化视频上传失败: ${error.response?.data?.error?.message || error.message}`);\n// after: include TikTok error code and preserve status for better diagnostics\nconst apiErr = error.response?.data?.error;\nthrow new BadRequestException(\n  `初始化视频上传失败: [${apiErr?.code ?? 'UNKNOWN'}] ${apiErr?.message ?? error.message}`\n);","handlingStrategy":"validation","validationCode":"function assertValidInboxUploadInit(accessToken, videoSize, chunkSize = 5 * 1024 * 1024) {\n  if (!accessToken || typeof accessToken !== 'string') throw new Error('缺少有效的 TikTok accessToken');\n  if (!Number.isFinite(videoSize) || videoSize <= 0) throw new Error('videoSize 必须为正数字（字节）');\n  if (chunkSize < 5 * 1024 * 1024 || chunkSize > 64 * 1024 * 1024) throw new Error('chunkSize 必须在 5MB–64MB 之间');\n}","typeGuard":"function hasTikTokErrorPayload(e: unknown): e is { response: { data: { error: { code: string; message: string } } } } {\n  return typeof e === 'object' && e !== null &&\n    'response' in e && typeof (e as any).response?.data?.error?.message === 'string';\n}","tryCatchPattern":"try {\n  const initData = await tiktokService.initVideoUpload(accessToken, videoBuffer.length);\n} catch (e) {\n  if (e instanceof BadRequestException) {\n    const msg = e.message;\n    if (msg.includes('access_token') || msg.includes('invalid')) {\n      // re-authenticate then retry once\n    } else if (msg.includes('size') || msg.includes('chunk')) {\n      // fix source_info values\n    }\n  }\n  throw e;\n}","preventionTips":["Always compute videoSize from the actual Buffer/file (videoBuffer.length or fs.statSync().size), never a cached value.","Keep chunkSize within TikTok's documented 5MB–64MB range.","Refresh access tokens proactively before long upload flows and verify scopes include video.upload.","Log error.response.data at init time so TikTok's error.code is captured for diagnosis.","Confirm the app is production-audited; sandbox apps have restricted upload/publish behavior."],"tags":["tiktok","api-error","video-upload","http-client","nestjs"],"backgroundTag":"upstream-api-request-failed","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}