What is a circular dependency?

What is a circular dependency?

Megan Sullivan

While working with predecessors on a schedule, you might come across a situation in which the system won't let you add a predecessor to a task. If this happens, the predecessor box will turn red and the predecessor will not update after you enter it.

This is what's called a circular dependency, and it occurs in two situations.


Task-Level Circular Dependency

This is the more common and straightforward type of circular dependency. A circular dependency occurs when a task is dependent on itself. For example, if Task B is dependent on Task A, you cannot set Task A to be dependent on Task B at the same time.

It can get a little more confusing when you have a whole string of predecessors and tasks. We recommend tracing back the line of predecessors, moving from task to task to figure out what is causing the circular dependency so that you can fix it.


Milestone-Level Circular Dependency

The second kind of circular dependency is rarer, but also a lot trickier to understand. This milestone-level circular dependency deals with dependencies between different milestones or sub-levels of tasks in CoConstruct.

This is best explained visually:

When you make a task in one milestone dependent on a task in another milestone, you create a dependency in a specific direction between your milestones (forward or backward in your schedule). After you create this initial dependency between milestones, you cannot add a predecessor that would create a dependency in the opposite direction between those same milestones.

This limitation is milestone specific, and you can work around it by rearranging your tasks or by creating a new milestone (an unindented, top-level task) for the dependent task. By pulling your dependent task out of the nested hierarchy, you can ensure that the relationship you're trying to create will not conflict with the other dependencies that you have in place between your milestones.

If rearranging your tasks isn't an option, you can also think about using alternative dependency types. Instead of using a Finish-To-Start (FS) predecessor on Task A for example, consider applying a Start-To-Finish (SF) predecessor on Task B in order to build a similar, though inverted, relationship.


If you are ever having trouble pinpointing where the circular dependency is being created, don't hesitate to contact Support. We will be more than happy to take a look and help you work through it!