{"record":{"id":"9cd94bb7a2fe6ebf","repo":"yikart/AiToEarn","slug":"invalidmodel-9cd94b","errorCode":"InvalidModel","errorMessage":"ResponseCode.InvalidModel","messagePattern":"ResponseCode\\.InvalidModel","errorType":"error_code","errorClass":"AppException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/apps/aitoearn-ai/src/core/draft-generation/draft-generation.service.ts","lineNumber":233,"sourceCode":"      return task\n    }\n\n    const queue = await this.queueService.getDraftGenerationQueueInfo(task.id)\n    if (!queue) {\n      return task\n    }\n\n    return { ...task, queue }\n  }\n\n  private async attachQueueInfoToTasks<T extends { id: string, status: AiLogStatus }>(tasks: T[]): Promise<Array<DraftGenerationTaskWithQueue<T>>> {\n    return await Promise.all(tasks.map(task => this.attachQueueInfo(task)))\n  }\n\n  private getVideoDraftModelConfig(model: string) {\n    const modelConfig = config.ai.models.video.generation.find(m => m.name === model)\n    if (!modelConfig) {\n      throw new AppException(ResponseCode.InvalidModel)\n    }\n\n    return modelConfig\n  }\n\n  private resolveVideoReferenceMode(\n    modelConfig: ReturnType<DraftGenerationService['getVideoDraftModelConfig']>,\n    videoUrls?: string[],\n    audioUrls?: string[],\n  ): 'multi-ref' | 'video2video' | undefined {\n    const hasVideoReference = (videoUrls?.length ?? 0) > 0\n    const hasAudioReference = (audioUrls?.length ?? 0) > 0\n    if (!hasVideoReference && !hasAudioReference) {\n      return undefined\n    }\n\n    if (modelConfig.modes.includes('multi-ref')) {\n      return 'multi-ref'","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-ai/src/core/draft-generation/draft-generation.service.ts#L215-L251","documentation":"getVideoDraftModelConfig in DraftGenerationService looks up the requested video generation model name in config.ai.models.video.generation and throws InvalidModel when no entry matches. This validates the video-draft generation model before resolving reference mode or dispatching the generation task.","triggerScenarios":"A video draft generation request supplies a model name that is not present in config.ai.models.video.generation (typo, deprecated model, or client sending a model from another environment's config).","commonSituations":"Video provider retired a model name and config was updated, but cached clients still send the old name; staging/production configs have different model lists; frontend model picker hardcoded instead of driven by server config.","solutions":["Use a model name exactly matching an entry in config.ai.models.video.generation","Update config to include the requested model, or remove it from the client's offered list","Serve the valid model list to clients from config so they cannot submit unknown names","Check environment: the model may exist in another env's config but not this one"],"exampleFix":"// before\ngenerateVideoDraft({ model: 'kling-v1-5', ... })\n// after (config has 'kling-v2')\ngenerateVideoDraft({ model: 'kling-v2', ... })","handlingStrategy":"validation","validationCode":"const validVideoModels = config.ai.models.video.generation.map(m => m.name)\nif (!validVideoModels.includes(request.model)) {\n  throw new Error(`Unknown video model ${request.model}; valid: ${validVideoModels.join(',')}`)\n}","typeGuard":"function isKnownVideoModel(name: string): boolean {\n  return config.ai.models.video.generation.some(m => m.name === name)\n}","tryCatchPattern":"try {\n  const task = await draftGenerationService.createVideoDraft(dto)\n} catch (e) {\n  if (e instanceof AppException && e.code === ResponseCode.InvalidModel) {\n    return { error: 'invalid-model', validModels: config.ai.models.video.generation.map(m => m.name) }\n  }\n  throw e\n}","preventionTips":["Drive frontend model dropdowns from the server's configured model list","Purge deprecated model names from clients when the provider retires them","Verify the model exists in the target environment's config before deploying client changes","Store task model preferences as validated enums, not free-form strings"],"tags":["configuration","model-selection","validation","video-generation"],"backgroundTag":"model-not-configured","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}