yikart/AiToEarn · error · AppException

InvalidAiTaskId

InvalidAiTaskId

Error message

ResponseCode.InvalidAiTaskId

What it means

InvalidAiTaskId thrown in transformToCommonResponse when a video AI log is in a terminal/succeeded state (not Generating, not Failed) but has no `response` payload stored. The task cannot be mapped to a common response because the provider result is missing, and the service reports this as an invalid/unusable task record.

Source

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

    const finishedAt = aiLog.duration
      ? new Date(aiLog.startedAt.getTime() + aiLog.duration)
      : undefined

    if (aiLog.status === AiLogStatus.Failed) {
      return {
        ...base,
        status: TaskStatus.Failure,
        videoUrl: undefined,
        coverUrl: savedMedia.coverUrl ? FileUtil.buildUrl(savedMedia.coverUrl) : undefined,
        mediaId: savedMedia.mediaId,
        groupId: savedMedia.groupId,
        error: { message: aiLog.errorMessage ?? 'Video task failed' },
        finishedAt,
      }
    }

    if (!aiLog.response) {
      throw new AppException(ResponseCode.InvalidAiTaskId)
    }

    const channelResult = this.getChannelTaskResult(aiLog)

    return {
      ...base,
      ...channelResult,
      coverUrl: savedMedia.coverUrl ? FileUtil.buildUrl(savedMedia.coverUrl) : undefined,
      mediaId: savedMedia.mediaId,
      groupId: savedMedia.groupId,
      finishedAt,
    }
  }

  async ensureSavedMediaByAiLogId(aiLogId: string): Promise<void> {
    const aiLog = await this.aiLogRepo.getById(aiLogId)
    if (!aiLog || aiLog.type !== AiLogType.Video) {
      return

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Verify the task id is correct and re-query — if the log was mid-write the response may appear shortly after.
  2. Inspect the aiLog document in MongoDB: check `status` vs presence of `response` to confirm data corruption.
  3. Trigger the status sync/callback path (ensureSavedVideoMedia / channel refresh) to backfill the response, or mark the log Failed so the failure branch returns instead of throwing.
  4. Fix the callback handler so `response` is saved atomically with the status change.

Example fix

// before
if (aiLog.status === 'success') return transformToCommonResponse(aiLog) // throws if response missing
// after
if (aiLog.status === 'success' && !aiLog.response) {
  return { status: TaskStatus.Failure, error: { message: 'provider response missing' } }
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const res = await videoService.getVideoTaskStatus({ taskId })
} catch (e) {
  if (e instanceof AppException && e.code === 'InvalidAiTaskId') {
    // treat as unrecoverable record; surface 'task record incomplete' to caller or re-sync from provider
  }
}

Prevention

When it happens

Trigger: Querying getVideoTaskStatus or listVideoTasks for a task whose aiLog reached a non-generating, non-failed status without a persisted provider `response` — e.g. status set to success by a callback that did not save the response body, or a log partially written.

Common situations: Provider callback succeeded but response-saving step failed or was skipped; data migration dropped the response field; task record manually edited in MongoDB; querying right at a race where status flipped but response write is pending.

Related errors


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