elsa-workflows/elsa-core · error · Exception
Cyclic dependency found
Error message
Cyclic dependency found
What it means
EnumerableTopologicalSortExtensions performs a depth-first topological sort of dependency-ordered items (used by Elsa features). When a cycle is detected and throwOnCycle is enabled, it throws a generic Exception('Cyclic dependency found').
Solutions
- Break the cycle by removing the back-dependency from one feature's Dependencies list
- Move shared logic into a lower-level feature that both depend on
- Review the feature dependency graph and ensure it forms a DAG
Example fix
// before
class FeatureA : FeatureBase { public override IEnumerable<Type> Dependencies => new[] { typeof(FeatureB) }; }
class FeatureB : FeatureBase { public override IEnumerable<Type> Dependencies => new[] { typeof(FeatureA) }; }
// after
class FeatureB : FeatureBase { public override IEnumerable<Type> Dependencies => Array.Empty<Type>(); } Defensive patterns
Strategy: validation
Validate before calling
// detect cycle before registering
var deps = new Dictionary<Type, IEnumerable<Type>> { [typeof(FeatureA)] = typeof(FeatureA).GetDependencies() /* etc */ };
// run sort with throwOnCycle: false and inspect remaining unsorted items Try / catch
try { features.TSort(f => f.Dependencies, f => f.DependsOn, throwOnCycle: true); } catch (Exception e) when (e.Message == "Cyclic dependency found") { logger.LogError("Feature dependency cycle detected"); } Prevention
- Keep feature dependency lists one-directional
- Extract shared services into a base feature both features depend on
- Review dependency graph after adding new features or upgrades
When it happens
Trigger: Registering features (or any items with Dependencies) such that A depends on B and B (directly or transitively) depends on A, then running the topological sort.
Common situations: Custom Elsa feature declaring a dependency on a feature that (transitively) depends back on it; copying dependency lists between features creating a loop; plugin conflicts after package upgrades.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- A conversation ID is required. (Parameter 'conversation')
- A conversation user ID is required. (Parameter…
- AI conversation entity metadata was not found.
- AI conversation table metadata was not found.
- Build() must be called before accessing services
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/26441da0543be027.
Report an issue: GitHub.
Appendix: source
Thrown at src/common/Elsa.Features/Extensions/EnumerableTopologicalSortExtensions.cs:36
foreach (var item in source)
Visit(item, visited, sorted, dependencies, throwOnCycle);
return sorted;
}
private static void Visit<T>(T item, ISet<T> visited, ICollection<T> sorted, Func<T, IEnumerable<T>> dependencies, bool throwOnCycle)
{
if (visited.Add(item))
{
foreach (var dep in dependencies(item))
Visit(dep, visited, sorted, dependencies, throwOnCycle);
sorted.Add(item);
}
else
{
if (throwOnCycle && !sorted.Contains(item))
throw new Exception("Cyclic dependency found");
}
}
}View on GitHub (pinned to fe9217bdfa)