DEV Community

Cover image for Toward Cycle Detection in AI automation workflows
Piotr Paradiuk
Piotr Paradiuk

Posted on

Toward Cycle Detection in AI automation workflows

TL;DR

Cycle detection in no-code/automation tools is often neglected — even though it's critical for user safety. This post explains:

  • Why non-tech users are vulnerable to loop errors
  • How AI (and LLMs) fail at graph-level reasoning
  • How to detect cycles in JavaScript using Graphlib
  • What's missing in today's tooling — and how we can fix it
  • Why visual loop safety is a UX problem, not just a backend concern

The Story

Automation is now table stakes in AI-enabled platforms. Prompt-chain editors, workflow builders, and logic engines are popping up in nearly every product category — from marketing to dev tools.

Despite the competition, few platforms have proper implementation of cycle detection.

Side note: Notably some tools have n-loops (aka repeaters) in their workflow, but it doesn't cover loop detection rather it actually allows for a certain amount of repeats.

The human factor

Humans get overwhelmed quickly when working with large graphs. Managing an 80–90 node decision tree? It’s easy to accidentally create an infinite loop — especially for non-developers, who make up a large share of users on workflow platforms

These systems are meant to let humans focus on intent, not technical structure. But let’s be honest — today’s AI-powered workflows are starting to look like miniature neural networks:

Loop graph

Why cycle isn't just a fancy dev word

In production, unnoticed cycles can trigger unnecessary API calls, data duplication, or even billing nightmares — especially in pay-per-execution platforms.

It's rarely a good idea or user intent to spawn a flow that just keeps repeating itself. The UI should clearly notify users when their graph contains a loop that prevents execution.

This isn’t just a technical safeguard — it’s a UX imperative. If a user can’t see that they’ve built a loop, or doesn’t understand why their automation breaks, the failure becomes a design problem, not a logic one. Visual loop safety is about clarity, not just correctness.

It's harder to detect infinite loops when data travels back and forth different integrations and comes back to the target platform, but it's surely a job we can do when designing data flows in the platform itself.

Real world scenario

In Infinite Cycles in Monday.com Automations, I've described how Monday.com automation allow infinite loop in their automations (and also smartly protects itself from negative consequences).

Side note about AI

If you pondered whether AI could help you find infinite cycles in your workflow, recent studies show that graph analysis — especially dynamic semantics like control flow or AST traversal — is one of the weak points for large language models (LLMs).

“Our study highlights that while LLMs have a talent for understanding code syntax, they struggle with comprehending code semantics, particularly dynamic semantics… which include abstract syntax trees (AST), control flow graphs (CFG), and call graphs (CG).”
— LMs: Understanding Code Syntax and Semantics for Code Analysis, Ma et al. (2023) https://arxiv.org/abs/2305.12138

Looks like a job for a human

So what can we use in the JavaScript ecosystem — the world’s most popular frontend stack — to detect loops directly in the browser?

We'd need a multigraph edge-aware ability to find cycles. Each edge could be an entirely different automation trigger, and we don't always merge all processes together. Process are often quite independent recipes.

Well, in JS world, there is Graphlib

Graphlib does support multigraphs ({ multigraph: true }).

But: its alg.findCycles() does not differentiate between parallel edges (i.e., multiple edges between the same pair of nodes).

That means it will properly recognise cycles, but it will not distinguish whether it was edge e1 or e2 from A → B that formed the cycle.

In complex automations, where multiple rules connect the same steps under different conditions, this limitation can make it hard to trace which specific rule or edge is creating a loop — frustrating users who just want to fix the problem.

Another library graphology also doesn't natively track edge-aware cycles in multigraphs.

While there's clearly a gap in the JavaScript ecosystem for formally enumerating edge-specific cycle paths, I'll stick to a simple detection for now using graphlib to demonstrate how using graph lookup we can prevent cycle loops.

Data structure

As mentioned before, many tools allow customers to create infinite cycles. In example below you can see a cycle between 'Working on it' and 'Stuck' Statuses.

Here is how the above data is represented in Monday.com automation data -- while it's not a graph, we can use this format to detect nodes that have similar trigger and statusColumnValue.

{
  "automations": [
    {
      "id": 133547104,
      "config": {
        "0": {
          "statusColumnValue": {
            "index": 0
          }
        },
        "1": {
          "statusColumnValue": {
            "index": 2
          }
        }
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Now let's convert this into graph, and analyse the cycles with Graphlib.

Side note: Graphlib uses Tarjan algorithm, see: https://github.com/dagrejs/graphlib/blob/master/lib/alg/find-cycles.js

LynX, CC BY-SA 3.0 <https://creativecommons.org/licenses/by-sa/3.0>, via Wikimedia Commons

After streaming the automation json format from Monday.com into graphlib, it properly detects cycles:

import graphlib from 'graphlib';
const { Graph, alg } = graphlib;

/**
 * Builds a directed graph using integer status indices as nodes.
 * @param {Array} automations - Array of automation config objects
 * @returns {{ activeGraph: Graph, fullGraph: Graph }}
 */
export function buildGraphs(automations) {
    const activeGraph = new Graph({ directed: true });
    const fullGraph = new Graph({ directed: true });
    automations.forEach(auto => {
        const from = auto.config["0"].statusColumnValue.index;
        const to = auto.config["1"].statusColumnValue.index;

        fullGraph.setEdge(String(from), String(to), `automation #${auto.id}`);
        if (auto.active) {
            activeGraph.setEdge(String(from), String(to), `automation #${auto.id}`);
        }
    });

    return { activeGraph, fullGraph };
}

/**
 * Finds all cycles in a graph where a path loops back to the same node.
 * @param {Graph} graph
 * @returns {Array<Array<string>>} - Array of node paths forming cycles
 */
export function detectCycles(graph) {
    return alg.findCycles(graph);
}
Enter fullscreen mode Exit fullscreen mode

Combine this with a simple test..
source: https://github.com/piotrdiuk/graphoman/blob/main/test/graphDetection.test.js

...and we'll get:

Nodes: [ '0', '2' ]
Edges: [ { v: '0', w: '2' }, { v: '2', w: '0' } ]
Cycles detected: [ [ '2', '0' ] ]
Enter fullscreen mode Exit fullscreen mode

This confirms that Graphlib detects the cycle properly — but not the edge-level detail.

While this basic approach works for flagging loops, a more robust solution should:

  • Track which edge (or automation) causes the cycle

  • Prioritise flagging the recipe that breaks most connections,

  • Allow per-recipe cycle isolation,

  • Offer actionable feedback to users.

Toward Better Workflow Safety

The next step is designing a universal, edge-aware graph format that can represent automations with full traceability: not just "there's a loop" — but "this specific automation causes a loop from A to B to A".

That format should be:

  • Easy to generate from automation data,

  • Friendly to visualisation tools,

  • Ready for plug-in cycle-checkers or debuggers.

Because in the end, automation should empower non-technical users — not trap them in invisible accidental loops.

Cycle safety isn’t just a backend concern — it’s a product experience issue. If loops confuse or block users, that’s on the tool, not them. Every invisible loop puts the user at risk of frustration, wasted time, and broken trust. Smarter graph tooling, even something as lightweight as Graphlib with custom edge tracking, brings us one step closer to reliable, human-friendly automation.

Let me know if you know or are building something similar to help tackle this challange in JS!

Top comments (0)