{"record":{"id":"863ee7f068b72e18","repo":"yikart/AiToEarn","slug":"canvas-not-provided-and-no-vid-video-source-fou","errorCode":null,"errorMessage":"Canvas not provided and no vid:// video source found in Track. Please provide Canvas dimensions or use vid:// video sources.","messagePattern":"Canvas not provided and no vid:// video source found in Track\\. Please provide Canvas dimensions or use vid:// video sources\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"project/aitoearn-backend/apps/aitoearn-ai/src/core/agent/mcp/volcengine/video-edit.mcp.ts","lineNumber":55,"sourceCode":"  ): Promise<{ Width: number, Height: number }> {\n    if (canvas) {\n      return canvas\n    }\n\n    let vid: string | undefined\n    for (const layer of track) {\n      for (const element of layer) {\n        if (element.Type === 'video' && element.Source?.startsWith('vid://')) {\n          vid = element.Source.replace('vid://', '')\n          break\n        }\n      }\n      if (vid)\n        break\n    }\n\n    if (!vid) {\n      throw new Error('Canvas not provided and no vid:// video source found in Track. Please provide Canvas dimensions or use vid:// video sources.')\n    }\n\n    const mediaInfos = await this.volcengineService.getMediaInfos({ Vids: vid })\n    const sourceInfo = mediaInfos.MediaInfoList?.[0]?.SourceInfo\n\n    if (!sourceInfo?.Width || !sourceInfo?.Height) {\n      throw new Error(`Canvas not provided and failed to retrieve video dimensions for vid://${vid}. Please provide Canvas dimensions explicitly.`)\n    }\n\n    return { Width: sourceInfo.Width, Height: sourceInfo.Height }\n  }\n\n  /**\n   * 提交视频编辑任务（直接使用 Track 结构）\n   */\n  createSubmitDirectEditTaskTool(userId: string, userType: UserType) {\n    return wrapTool(\n      this.logger,","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-ai/src/core/agent/mcp/volcengine/video-edit.mcp.ts#L37-L73","documentation":"getVideoDetail requires both videoId and accountId query parameters. Either missing triggers BadRequestException('videoId和accountId是必须的'). accountId is needed to resolve the stored user access token, videoId identifies the video to fetch.","triggerScenarios":"GET the video-detail route where ?videoId= or ?accountId= (or both) are absent or empty strings.","commonSituations":"Deep link built from a video list omits the account context, or a stale cached video entry no longer carries the originating accountId.","solutions":["Include both ?videoId=<id>&accountId=<id> in the request.","Persist the accountId alongside video references in the client so detail views always have it.","Validate both params client-side before navigating to the detail route."],"exampleFix":"// before\nawait api.get(`/plat/tiktok/video/${videoId}`);\n// after\nawait api.get(`/plat/tiktok/video/${videoId}?accountId=${encodeURIComponent(accountId)}`);","handlingStrategy":"validation","validationCode":"if (!videoId || !accountId) throw new Error('videoId和accountId是必须的');\nawait api.get(`/plat/tiktok/video/${videoId}`, { params: { accountId } });","typeGuard":"function isVideoDetailQuery(v): v is { videoId: string; accountId: string } {\n  return typeof v?.videoId === 'string' && v.videoId.length > 0 && typeof v?.accountId === 'string' && v.accountId.length > 0;\n}","tryCatchPattern":"try {\n  return await api.get(`/plat/tiktok/video/${videoId}`, { params: { accountId } });\n} catch (e) {\n  if (e.response?.status === 400) console.warn('缺少videoId/accountId，跳过详情加载');\n  throw e;\n}","preventionTips":["Persist accountId alongside every stored video reference","Validate route/query params before navigating to detail views","Avoid template strings with possibly-undefined variables in URL builders"],"tags":["validation","missing-parameter","query-params"],"backgroundTag":"missing-required-parameter","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}