yikart/AiToEarn · error · AppException

InvalidModel

InvalidModel

Error message

ResponseCode.InvalidModel

What it means

InvalidModel thrown by VideoService.requireChannel when the channel-specific video service (e.g. relayVideoService) is not available/injected. The generic video facade requires the target channel's service to be registered; if the optional dependency is undefined, the requested model's channel cannot be served.

Source

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

  constructor(
    private readonly userRepo: UserRepository,
    private readonly aiLogRepo: AiLogRepository,
    private readonly modelsConfigService: ModelsConfigService,
    private readonly assetsService: AssetsService,
    private readonly videoMetadataService: VideoMetadataService,
    private readonly materialGroupRepository: MaterialGroupRepository,
    private readonly mediaRepository: MediaRepository,
    private readonly volcengineVideoService: VolcengineVideoService,
    private readonly openaiVideoService: OpenAIVideoService,
    private readonly grokVideoService: GrokVideoService,
    private readonly dashscopeVideoService: DashscopeVideoService,
    @Optional() private readonly relayVideoService?: RelayVideoService,
  ) {}

  private requireChannel<T>(service: T | undefined): T {
    if (!service) {
      throw new AppException(ResponseCode.InvalidModel)
    }
    return service
  }

  /**
   * 用户视频生成(通用接口)
   */
  async userVideoGeneration(request: UserVideoGenerationRequestDto) {
    const { model, groupId, userId } = request

    if (groupId) {
      const group = await this.materialGroupRepository.getInfo(groupId)
      if (!group || group.userId !== userId) {
        throw new AppException(ResponseCode.MaterialGroupNotFound)
      }
    }

    const modelConfig = this.modelsConfigService.config.video.generation.find(m => m.name === model)

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Enable/register the missing channel service (import the Relay video module or set the enabling env/config)
  2. Pick a model whose channel service is available in this deployment
  3. Check that @Optional() RelayVideoService is actually provided in the module providers list
  4. Verify models config doesn't advertise channels the deployment can't serve

Example fix

// before (module)
providers: [VideoService] // RelayVideoService missing
// after
providers: [VideoService, RelayVideoService]
// or guard the caller
const service = channel === 'relay' ? relayVideoService : dashscopeVideoService
if (!service) throw new AppException(ResponseCode.InvalidModel)
Defensive patterns

Strategy: validation

Validate before calling

const service = channel === 'relay' ? relayVideoService : dashscopeVideoService
if (!service) {
  throw new Error(`Channel service unavailable for model ${model}; enable/register the channel module`)
}

Type guard

function channelAvailable<T>(s: T | undefined | null): s is T {
  return s !== undefined && s !== null
}

Try / catch

try {
  await videoService.userVideoGeneration(req)
} catch (e) {
  if (e instanceof AppException && e.code === ResponseCode.InvalidModel) {
    // fall back to a model whose channel is registered, or surface 'channel not enabled in this deployment'
  } else throw e
}

Prevention

When it happens

Trigger: userVideoGeneration, extractInput, or getChannelTaskResult resolve the channel service via requireChannel(service) and the service is undefined — e.g. RelayVideoService is @Optional() and not provided because the Relay module/config is disabled or missing.

Common situations: Relay feature flag/env var not enabled in this deployment; module not imported so the provider isn't registered; requesting a model whose channel maps to a service that isn't configured; DI misconfiguration after refactoring.

Related errors


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