@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 bothimportslists. - The order in which Nest creates them is not guaranteed.
- The better fix is to extract the shared logic or use events.
Read more