yikart/AiToEarn · error · AppException
AiLogNotFound
AiLogNotFound
Error message
ResponseCode.AiLogNotFound
What it means
DraftGenerationService.getTask fetches an AI log by id AND (userId, userType) via aiLogRepository.getByIdAndUserId; when no document matches, it throws AppException(ResponseCode.AiLogNotFound). The ownership scoping means a valid task id belonging to another user is indistinguishable from a nonexistent id.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-ai/src/core/draft-generation/draft-generation.service.ts:170
constructor(
private readonly materialGroupRepository: MaterialGroupRepository,
private readonly materialRepository: MaterialRepository,
private readonly aiLogRepository: AiLogRepository,
private readonly queueService: QueueService,
private readonly videoService: VideoService,
private readonly assetsService: AssetsService,
private readonly videoMetadataService: VideoMetadataService,
private readonly aiAvailability: AiAvailabilityService,
private readonly imageService: ImageService,
private readonly mediaRepository: MediaRepository,
private readonly draftGenerationPlannerService: DraftGenerationPlannerService,
private readonly draftGenerationMemoryService: DraftGenerationMemoryService,
) { }
async getTask(taskId: string, userId: string, userType: UserType) {
const aiLog = await this.aiLogRepository.getByIdAndUserId(taskId, userId, userType)
if (!aiLog) {
throw new AppException(ResponseCode.AiLogNotFound)
}
return await this.attachQueueInfo(aiLog)
}
async listTasks(dto: QueryDraftGenerationTasksDto, userId: string, userType: UserType) {
const tasks = await this.aiLogRepository.listByIdsAndUserId(dto.taskIds, userId, userType)
return await this.attachQueueInfoToTasks(tasks)
}
async listTasksWithPagination(dto: ListDraftGenerationTasksDto, userId: string, userType: UserType) {
const [tasks, total] = await this.aiLogRepository.listWithPagination({
...dto,
userId,
userType,
type: AiLogType.DraftGeneration,
})
return [await this.attachQueueInfoToTasks(tasks), total] as const
}View on GitHub (pinned to d3aa8bea5b)
Solutions
- Verify the taskId belongs to the authenticated userId/userType making the request
- Re-create the task if the id came from another environment or expired retention window
- Confirm the userType in the auth context matches the one used at task creation
- Handle AiLogNotFound in the polling client as a terminal 'task unknown' state instead of retrying forever
Example fix
// before
const task = await getTask(taskId, currentUserId, UserType.User) // taskId owned by another user
// after
const ownedTaskIds = (await listTasks({ taskIds: [taskId] }, currentUserId, UserType.User))
if (!ownedTaskIds.length) throw new AppException(ResponseCode.AiLogNotFound) // fail fast client-side, don't poll foreign ids Defensive patterns
Strategy: try-catch
Validate before calling
// client-side: only poll ids returned by your own create call, persisted with the same auth context
if (!createdTaskIds.includes(taskId)) {
throw new Error(`taskId ${taskId} was not created by this user/session`)
} Try / catch
try {
const task = await draftGenerationService.getTask(taskId, userId, userType)
} catch (e) {
if (e instanceof AppException && e.code === ResponseCode.AiLogNotFound) {
return { status: 'unknown' } // stop polling; do not retry
}
throw e
} Prevention
- Treat AiLogNotFound as terminal when polling — the id is foreign or expired, retrying won't help
- Ensure the userType in the request auth context matches the one used at task creation
- Handle token/user rotation: re-derive userId from the current auth, not cached values
- Never share task ids across environments; ids are database- and user-scoped
When it happens
Trigger: Polling a draft-generation task with a taskId that does not exist, was created by a different userId/userType, or with a JWT/auth context whose userType differs from the one recorded on the log (e.g. querying as user vs admin/agent type).
Common situations: Client polls with a task id from a previous environment/database; auth token rotated so the userId no longer matches the log owner; task id truncated or type-confused (stringified ObjectId vs custom id); calling getTask before task creation was persisted.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/ef6fcf2adfb104a3.
Report an issue: GitHub.