yikart/AiToEarn · error · AppException

InvalidAiTaskId

InvalidAiTaskId

Error message

InvalidAiTaskId

What it means

remixVideo looks up the original video task with aiLogRepo.getByIdAndUserId(videoId, userId, userType) and requires an existing log whose channel is OpenAI and which has a non-empty taskId. If the log is missing, belongs to another user, has a different channel (e.g. Veo), or lacks a provider taskId, it throws AppException(ResponseCode.InvalidAiTaskId).

Source

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

      status: AiLogStatus.Generating,
    })

    return {
      ...result,
      id: aiLog.id,
    }
  }

  /**
   * OpenAI 视频 Remix
   */
  async remixVideo(request: UserOpenAIVideoRemixRequestDto) {
    const { userId, userType, videoId, prompt } = request

    // 首先查找原视频任务
    const aiLog = await this.aiLogRepo.getByIdAndUserId(videoId, userId, userType)
    if (!aiLog || aiLog.channel !== AiLogChannel.OpenAI || !aiLog.taskId) {
      throw new AppException(ResponseCode.InvalidAiTaskId)
    }

    const model = aiLog.model

    const startedAt = new Date()
    const result = await this.aiAvailability.executeAsync(
      { provider: 'openai', operation: 'videoGeneration', model },
      () => this.openaiLibService.remixVideo(aiLog.taskId!, prompt),
      r => r.id,
    )

    const newAiLog = await this.aiLogRepo.create({
      userId,
      userType,
      taskId: result.id,
      model,
      channel: AiLogChannel.OpenAI,
      startedAt,

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Pass a valid OpenAI-channel videoId owned by the requesting user
  2. Verify the original video task completed creation and has a stored taskId (query the ai_log collection)
  3. Check userId/userType match the owner of the original task

Example fix

// before
remixVideo({ videoId: veoTaskLogId, ... }) // wrong channel
// after
const log = await aiLogRepo.getByIdAndUserId(videoId, userId, userType)
if (log?.channel === AiLogChannel.OpenAI && log.taskId) { await remixVideo({ videoId, ... }) }
Defensive patterns

Strategy: validation

Validate before calling

const log = await aiLogRepo.getByIdAndUserId(videoId, userId, userType)
if (!log || log.channel !== AiLogChannel.OpenAI || !log.taskId) {
  throw new Error('Video is not a remixable OpenAI task for this user')
}

Type guard

function isRemixableOpenAILog(log: AiLog | null): log is OpenAIVideoAiLog & { taskId: string } {
  return !!log && log.channel === AiLogChannel.OpenAI && typeof log.taskId === 'string' && log.taskId.length > 0
}

Try / catch

try {
  await openaiVideoService.remixVideo({ videoId, prompt })
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.InvalidAiTaskId) {
    // surface 'original video not found or not remixable' to the caller
  }
}

Prevention

When it happens

Trigger: Calling remixVideo with a videoId that (a) does not exist, (b) belongs to a different userId/userType, (c) was created via a non-OpenAI channel, or (d) has no OpenAI taskId stored (task creation never completed).

Common situations: Client passes the internal aiLog id from another provider's generation; user A tries to remix user B's video; the original generation failed before a provider taskId was persisted; stale/cached videoId after database cleanup.

Related errors


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