CodePark/ questions / Providers & dependency injection
START PRACTICINGPRACTICE
Backend question · NestJS › Providers & dependency injection

What causes a circular dependency error in Nest and how do you resolve it, both between providers and between modules?

@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private common: CommonService,
  ) {}
}

A circular dependency happens when A needs B and B needs A. Nest can't create either one first. A related cause is barrel files (index.ts files that re-export other files). With them, an import can still be undefined when the decorator reads it.

How to resolve it:

  • Between providers: wrap the injection on both sides in @Inject(forwardRef(() => OtherService)).
  • Between modules: use imports: [forwardRef(() => OtherModule)] on both sides.
  • Or get one side lazily, when it's needed, through ModuleRef.

forwardRef delays reading the reference until the class is defined. The order in which Nest creates the two is not guaranteed. So neither constructor should rely on the other being fully ready.

Usually the better fix is a redesign. Move the shared logic into a third provider or module, or replace the back-reference with events.

  • A circular dependency means A depends on B and B depends on A.
  • For providers, use @Inject(forwardRef(() => X)) on both sides.
  • For modules, use forwardRef(() => XModule) in both imports lists.
  • The order in which Nest creates them is not guaranteed.
  • The better fix is to extract the shared logic or use events.