#Using registerAsync on dynamic module errors about module's argument dependency at index[0]

4 messages · Page 1 of 1 (latest)

hoary grotto
#

**TLDR: **
Booting an application that uses registerAsync() on a dynamic module fails to resolve dependencies, always at index 0, no matter how I order the injection list, no matter what I inject:

Nest can't resolve dependencies of the CONFIGURABLE_MODULE_OPTIONS[c0eb100884e61f001eea2] (?, Symbol(NAME), Symbol(VERSION), Symbol(INSTANCE_ID)). Please make sure that the argument Symbol(APP_OPTIONS) at index [0] is available in the CustomModule context.

Detailed version:

On NestJS 10.0.5, I have a custom dynamic module (in an NPM package) that uses

import { ConfigurableModuleBuilder } from "@nestjs/common";
import { type ModuleOptions } from "../lib/ModuleOptions.interface.js";
export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ModuleOptions>().build();

and

import { DiscoveryModule } from "@golevelup/nestjs-discovery";
@Module({
  imports: [DiscoveryModule],
  providers: [...], // there are almost exclusively FactoryProviders, some with OnModuleInit and OnApplicationBootstrap, here
})
export class CustomModule extends ConfigurableModuleClass {}

Then, in my actual Application, I have

@Module({
  imports: [
    ConfigModule,
    appMetadataModule, // provides injection tokens NAME, VERSION, INSTANCE_ID
    CustomModule.registerAsync({
      inject: [APP_OPTIONS, NAME, VERSION, INSTANCE_ID],
      useFactory: (appOptions: AppOptions, name: string, version: string, instanceId: string) => {
        return ...;
      },
    }),
  ],
  providers: [appOptionsFactory] // depends on ConfigModule
})
export class MyApplicationModule {}

When booting the application, I get the error

Nest can't resolve dependencies of the CONFIGURABLE_MODULE_OPTIONS[c0eb100884e61f001eea2] (?, Symbol(NAME), Symbol(VERSION), Symbol(INSTANCE_ID)). Please make sure that the argument Symbol(APP_OPTIONS) at index [0] is available in the CustomModule context.
#

Even if I strip it down to

@Module({
  imports: [
    ConfigModule,
    CustomModule.registerAsync({
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => configService as any,
    }),
  ]
})
export class MyApplicationModule {}

it fails with

Nest can't resolve dependencies of the CONFIGURABLE_MODULE_OPTIONS[3f2bb741ea84872eeaacf] (?). Please make sure that the argument ConfigService at index [0] is available in the CustomModule context.
#

Side note:

When I instead use

    CustomModule.register(customModuleOptions),

It boots up just fine. However, I need it to work with registerAsync.

turbid coyote
#

In this:

@Module({
  imports: [
    ConfigModule,
    appMetadataModule, // provides injection tokens NAME, VERSION, INSTANCE_ID
    CustomModule.registerAsync({
      inject: [APP_OPTIONS, NAME, VERSION, INSTANCE_ID],
      useFactory: (appOptions: AppOptions, name: string, version: string, instanceId: string) => {
        return ...;
      },
    }),
  ],
  providers: [appOptionsFactory] // depends on ConfigModule
})
export class MyApplicationModule {}

The imports of MyApplicationModule are not available to CustomModule's context, and so the inject cannot find the correct tokens and values to inject. Instead, you should use the imports of the CustomModule to provide those modules and their exports to the CustomModule's context and allow the useFactory to work as desired