yikart/AiToEarn · error · AppException

InvalidAiTaskId

InvalidAiTaskId

Error message

InvalidAiTaskId

What it means

In GrokVideoService.getTask, the logId is resolved with aiLogRepo.getByIdAndUserId(logId, userId, userType). The request is rejected with AppException(ResponseCode.InvalidAiTaskId) when the log is not found or is invalid for Grok video polling: it has no taskId, is not of type AiLogType.Video, or its channel is not AiLogChannel.Grok. This guards that users can only query their own valid Grok video tasks.

Source

Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/ai/video/grok/grok.service.ts:273

  extractInput(request: GrokVideoAiLog['request']) {
    return {
      prompt: request.prompt || '',
      image: request.referenceImages ?? request.image,
      duration: request.duration,
      aspectRatio: request.aspectRatio,
      resolution: request.resolution,
      videoUrl: request.videoUrl,
    }
  }

  /**
   * 用户查询任务状态(含实时查询 Grok API)
   */
  async getTask(userId: string, userType: UserType, logId: string): Promise<GrokVideoCallbackDto> {
    const aiLog = await this.aiLogRepo.getByIdAndUserId(logId, userId, userType)

    if (aiLog == null || !aiLog.taskId || aiLog.type !== AiLogType.Video || aiLog.channel !== AiLogChannel.Grok) {
      throw new AppException(ResponseCode.InvalidAiTaskId)
    }
    const grokAiLog = aiLog as GrokVideoAiLog

    if (grokAiLog.status !== AiLogStatus.Generating) {
      return grokAiLog.response!
    }
    try {
      const result = await this.grokLibService.getVideoStatus(grokAiLog.taskId!)
      return await this.callback(result, grokAiLog)
    }
    catch (e) {
      let errorMessage: string = (e as Error).message
      let code = '500'
      if (e instanceof AxiosError) {
        const status = e?.response?.status
        if (status && status >= 400 && status < 500) {
          const data = e.response?.data
          errorMessage = data?.error || data?.code || `Grok API error (${status})`

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Confirm the logId is a valid Grok video log owned by the requesting userId/userType.
  2. Check the log document: type must be 'video', channel must be 'grok', and taskId must be set.
  3. Use the correct channel-specific status endpoint for logs from other providers.
  4. If the log is missing a taskId, the original submission failed — resubmit the generation instead of polling.

Example fix

// before
const res = await grokVideoService.getTask(userId, userType, dashscopeLogId) // wrong channel
// after
const res = aiLog.channel === AiLogChannel.Grok
  ? await grokVideoService.getTask(userId, userType, aiLog.id)
  : await dashscopeVideoService.getTask(userId, userType, aiLog.id)
Defensive patterns

Strategy: validation

Validate before calling

function canPollGrokTask(log: { id: string; userId: string; userType: string; type: string; channel: string; taskId?: string } | null, userId: string, userType: string): boolean {
  return !!log
    && log.userId === userId
    && log.userType === userType
    && log.type === 'video'
    && log.channel === 'grok'
    && !!log.taskId
}

Type guard

function isGrokVideoAiLog(log: any): log is GrokVideoAiLog {
  return log != null
    && typeof log.taskId === 'string' && log.taskId.length > 0
    && log.type === AiLogType.Video
    && log.channel === AiLogChannel.Grok
}

Try / catch

try {
  const status = await grokVideoService.getTask(userId, userType, logId)
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.InvalidAiTaskId) {
    // refresh log list / re-check ownership; do not retry blindly
  }
  throw e
}

Prevention

When it happens

Trigger: Calling getTask with (a) a logId that does not exist or belongs to another user/userType, (b) a log whose task record never got a provider taskId, (c) a non-video log id, or (d) a video log from a different channel (e.g. Dashscope) passed to the Grok service.

Common situations: Client caches log ids across environments or accounts; calling the Grok status endpoint with a DashScope task log id; task submission failed before taskId was persisted; deleted logs still referenced by the frontend.

Related errors


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