{"record":{"id":"dd917b171c87cb78","repo":"yikart/AiToEarn","slug":"http-response-status","errorCode":null,"errorMessage":"HTTP ${response.status}","messagePattern":"HTTP \\$\\{response\\.status\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"project/aitoearn-backend/apps/aitoearn-ai/src/core/agent/mcp/volcengine/volcengine.utils.ts","lineNumber":90,"sourceCode":"    }\n  }\n\n  /**\n   * 获取图片尺寸\n   * @param imageUrl 图片 URL\n   * @param logger 日志记录器\n   * @returns 图片的宽度和高度\n   */\n  static async getImageDimensions(\n    imageUrl: string,\n    logger: Logger,\n  ): Promise<{ width: number, height: number }> {\n    try {\n      logger.debug('[getImageDimensions] Fetching image dimensions', { url: imageUrl })\n\n      const response = await fetch(imageUrl)\n      if (!response.ok) {\n        throw new Error(`HTTP ${response.status}`)\n      }\n\n      const arrayBuffer = await response.arrayBuffer()\n      const buffer = Buffer.from(arrayBuffer)\n      const dimensions = sizeOf(buffer)\n\n      if (!dimensions.width || !dimensions.height) {\n        throw new Error('Failed to get image dimensions')\n      }\n\n      logger.debug('[getImageDimensions] Image dimensions retrieved', {\n        width: dimensions.width,\n        height: dimensions.height,\n      })\n\n      return {\n        width: dimensions.width,\n        height: dimensions.height,","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-ai/src/core/agent/mcp/volcengine/volcengine.utils.ts#L72-L108","documentation":"publishVideo requires createVideoDto.accountId (from the CreateVideoDto body) and a separate videoId body field. If either is missing it throws BadRequestException('accountId和videoId是必须的'). The flow publishes a previously uploaded video identified by videoId under the given TikTok account.","triggerScenarios":"POST the publish route with a body lacking accountId in the DTO object or lacking a top-level videoId field, or publishing before the upload step returned a videoId.","commonSituations":"Client tries to publish straight from a draft without first uploading (no videoId yet), or nests videoId inside the DTO instead of at the body top level where @Body('videoId') reads it.","solutions":["Include both { accountId, ..., videoId } at the top level of the JSON body.","Complete the upload step first and use the returned videoId.","Ensure videoId is a body field, not nested inside createVideoDto properties the controller doesn't read."],"exampleFix":"// before\nawait api.post('/plat/tiktok/publish', { accountId, title });\n// after\nawait api.post('/plat/tiktok/publish', { accountId, title, videoId: uploadResult.videoId });","handlingStrategy":"validation","validationCode":"if (!createVideoDto.accountId || !videoId) throw new Error('accountId和videoId是必须的');\nawait api.post('/plat/tiktok/publish', { ...createVideoDto, videoId });","typeGuard":"function canPublish(dto: unknown, videoId: unknown): dto is { accountId: string } & Record<string, unknown> {\n  return typeof (dto as any)?.accountId === 'string' && (dto as any).accountId.length > 0 && typeof videoId === 'string' && videoId.length > 0;\n}","tryCatchPattern":"try {\n  return await api.post('/plat/tiktok/publish', { ...dto, videoId });\n} catch (e) {\n  if (e.response?.status === 400) console.error('发布前必须先上传并拿到videoId');\n  throw e;\n}","preventionTips":["Always run upload first and use its returned videoId for publish","Put videoId at the top level of the JSON body, not nested","Gate the publish button on both accountId and videoId being set in state"],"tags":["validation","missing-parameter","request-body"],"backgroundTag":"missing-required-parameter","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}