yikart/AiToEarn · warning · Error

Canvas not provided and failed to retrieve video dimensions

Error message

Canvas not provided and failed to retrieve video dimensions for vid://${vid}. Please provide Canvas dimensions explicitly.

What it means

uploadVideo requires accountId (body field) and an uploaded file (multipart). If either is missing the controller throws BadRequestException('accountId和视频文件是必须的'). accountId resolves the access token; the file buffer is the video to upload.

Source

Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/agent/mcp/volcengine/video-edit.mcp.ts:62

      for (const element of layer) {
        if (element.Type === 'video' && element.Source?.startsWith('vid://')) {
          vid = element.Source.replace('vid://', '')
          break
        }
      }
      if (vid)
        break
    }

    if (!vid) {
      throw new Error('Canvas not provided and no vid:// video source found in Track. Please provide Canvas dimensions or use vid:// video sources.')
    }

    const mediaInfos = await this.volcengineService.getMediaInfos({ Vids: vid })
    const sourceInfo = mediaInfos.MediaInfoList?.[0]?.SourceInfo

    if (!sourceInfo?.Width || !sourceInfo?.Height) {
      throw new Error(`Canvas not provided and failed to retrieve video dimensions for vid://${vid}. Please provide Canvas dimensions explicitly.`)
    }

    return { Width: sourceInfo.Width, Height: sourceInfo.Height }
  }

  /**
   * 提交视频编辑任务(直接使用 Track 结构)
   */
  createSubmitDirectEditTaskTool(userId: string, userType: UserType) {
    return wrapTool(
      this.logger,
      VideoEditToolName.SubmitDirectEditTask,
      `Submit a video editing task using Volcengine Track structure.

**CRITICAL - ALL PosX/PosY Rules**:
- ALL PosX/PosY values are TOP-LEFT corner coordinates, NOT center point
- This applies to: transform, crop, delogo, and any other filter with PosX/PosY
- For full-screen video: ALWAYS use PosX: 0, PosY: 0

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Send multipart/form-data containing both a 'file' part and an 'accountId' field.
  2. Do not set Content-Type manually — let the HTTP client set the multipart boundary.
  3. Verify the file input has a selected file before submitting.

Example fix

// before
const fd = new FormData();
fd.append('file', videoFile);
await api.post('/plat/tiktok/upload', fd);
// after
const fd = new FormData();
fd.append('file', videoFile);
fd.append('accountId', accountId);
await api.post('/plat/tiktok/upload', fd);
Defensive patterns

Strategy: validation

Validate before calling

if (!accountId || !videoFile) throw new Error('accountId和视频文件是必须的');
const fd = new FormData();
fd.append('accountId', accountId);
fd.append('file', videoFile);

Type guard

function canUpload(accountId: unknown, file: unknown): accountId is string {
  return typeof accountId === 'string' && accountId.length > 0 && !!file && typeof (file as File).size === 'number';
}

Try / catch

try {
  return await api.post('/plat/tiktok/upload', fd);
} catch (e) {
  if (e.response?.status === 400) console.error('上传请求缺少accountId或文件,检查FormData字段');
  throw e;
}

Prevention

When it happens

Trigger: POST multipart to the upload route without the accountId form field, without a file part (field name expected by @UploadedFile, typically 'file'), or with a JSON content type instead of multipart/form-data.

Common situations: Client appends only the file to FormData but forgets form.append('accountId', id), the file input was left empty, or an interceptor forces Content-Type: application/json breaking multer parsing.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/64ac9f006f43ade1. Report an issue: GitHub.