[ideas] Proposal: include an example cycle in “dependency graph contains a cycle” errors (via igraph::find_cycle())
#1562
Replies: 2 comments 3 replies
-
|
|
Beta Was this translation helpful? Give feedback.
-
|
I do think a helper to return the igraph object representing the pipeline would be a good addition to |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Help
Description
Context / motivation
When the
targetsdependency graph contains a cycle,targetserrors with a generic message:This is correct but not very actionable for large pipelines with many targets. In practice, users then have to manually reconstruct the cycle (often by building the graph themselves and hunting the loop), which is slow and error-prone. An existing cycle short circuits many of the debugging tools available in
targets: you cannot runtar_visnetwork(),tar_outdated(), or other helper functions until the cycle is resolved. That makes it a particularly troublesome problem to deal with. I recently hunted down a cycle issue by runningdebugonce(targets:::tar_assert_target_dag)and using the new igraph functionfind_cycle()to pin down the problem in a local targets session, but it would be nice iftargetsjust printed out that information for you.Since
targetsalready represents the dependency graph as anigraphobject and usesigraph::is_dag()to validate that it is acyclic, I think it would be a significant usability improvement if the error reported one concrete cycle.Proposed approach
igraphnow exposesfind_cycle(), which returns a cycle as both a vertex sequence and an edge sequence. (This is a relatively new feature in igraph.) The idea is:igraph::find_cycle()is available, append an “Example cycle” section to the error message showing a representative loop.This would give immediate, actionable information while keeping the behavior unchanged for older igraph versions.
Example of
igraph::find_cycle()output (what users can already compute manually)Example cycle returned from a subgraph:
Vertices:
data_inputintermediate_productfinal_producthelper_dataEdges:
helper_data -> data_inputdata_input -> intermediate_productintermediate_product -> final_productfinal_product -> helper_dataFrom a user perspective, the useful output is the vertex path (with closure), e.g.
Current code location
The current check is in:
Implementation sketch
This helper appends a cycle report when possible. For long cycles it prints the first 5 and last 5 vertices/links to avoid extremely long error messages.
Behavior / UX notes
find_cycle()returns), rather than enumerating all cycles.Example:
Pipeline
Output
Example:
Pipeline
Output
find_cycle()is unavailable (older igraph), behavior remains unchanged (same current message).Testing ideas
igraphand assert the error includes “Example cycle” plus the expected vertex names.skip_if_not(exists("find_cycle", envir = asNamespace("igraph"), inherits = FALSE))so older igraph doesn’t fail CI.find_cycle()is not available.If this approach seems acceptable, I can convert this into an issue + PR.
Beta Was this translation helpful? Give feedback.
All reactions