yikart/AiToEarn · error · BadRequestException

accountId和publishId是必须的

Error message

accountId和publishId是必须的

What it means

checkPublishStatus needs both accountId (to resolve the account's access token) and publishId (the publish job ID returned by the upload/init flow) in the request body. Missing either yields this 400 BadRequestException. The publishId comes from a previous uploadAndPublishVideo/init step, so this error often means that earlier response was dropped.

Source

Thrown at project/aitoearn-electron/server/src/modules/plat/tiktok/tiktok.controller.ts:464

  @Post('videos/publish/status')
  @ApiOperation({ summary: '检查视频发布状态' })
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        accountId: { type: 'string', description: 'TikTok账号ID' },
        publishId: { type: 'string', description: '发布ID' }
      },
      required: ['accountId', 'publishId']
    }
  })
  async checkPublishStatus(
    @GetToken() systemToken: TokenInfo,
    @Body('accountId') accountId: string,
    @Body('publishId') publishId: string
  ) {
    if (!accountId || !publishId) {
      throw new BadRequestException('accountId和publishId是必须的');
    }

    const accessToken = await this.tikTokAuthService.getUserAccessToken(accountId);
    return this.tikTokService.checkPublishStatus(accessToken, publishId);
  }

  /**
   * 一键上传并发布视频(新版API三步法)
   */
  @Post('videos/publish')
  @ApiOperation({ summary: '一键上传并发布视频(新版API)' })
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        accountId: { type: 'string', description: 'TikTok账号ID' },
        title: { type: 'string', description: '视频标题' },

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Persist the publishId returned by the upload/init step and send it in every status check.
  2. Include accountId alongside publishId in the body.
  3. Only start polling after the publish-init call has successfully returned a publishId.

Example fix

// before
await api.post('/tiktok/video/publish/status', { accountId });
// after
await api.post('/tiktok/video/publish/status', { accountId, publishId });
Defensive patterns

Strategy: validation

Validate before calling

if (!publishJob?.accountId || !publishJob?.publishId) {
  throw new Error('Cannot check status: publishId must be stored from the init/upload response');
}

Type guard

function isPublishJob(j: { accountId?: string; publishId?: string }): j is { accountId: string; publishId: string } {
  return typeof j.accountId === 'string' && j.accountId !== '' &&
         typeof j.publishId === 'string' && j.publishId !== '';
}

Try / catch

try {
  const status = await api.post('/tiktok/video/publish/status', publishJob);
} catch (e) {
  if (e.response?.status === 400) {
    stopPolling();
    console.error('Missing accountId/publishId — publish job state lost');
  }
}

Prevention

When it happens

Trigger: Polling publish status before storing the publishId from the init/upload response, or calling without accountId.

Common situations: Status-poller jobs restarted after process restart losing the publishId; race where polling starts before the init call returns; accountId not persisted with the publish job.

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/729aa79749f15395. Report an issue: GitHub.