Loop inside a loop is not working

I am facing issue on using loop inside another loop. from loop_all_invoice expected data is send to next node. get_products_by_invoice is looping and sending data to next node as expected. but loop_on_products is not working as expected. it is sending only first batch data from loop_all_invoice. instead of loop in loop_on_products if I use split node, it works. But I need loop node to more validation. I tried split and then loop over node, but not getting same result.

I solved this type of errors a fiew times making de inside loop into a sub workflow, and calling it inside the first loop.

Hi @Md_Ashickur_Rahman You should consider the use of a sub-workflow for the inner loop. Thus, move get_products_by_invoice + loop_on_products + insert logic into a sub workflow and call this once per invoice from the outer loop. A nested Loop Over Items in same workflow keeps state and it will only run correct for first outer iteration. As i recommend is not to use nested loops as they can be hard to debug and decreases the workflow readability, hope this helps!

Hi @Md_Ashickur_Rahman

What you’re seeing is actually expected behavior. Loop Over Items keeps internal state, so when you nest it inside another loop in the same workflow, the inner loop only runs correctly for the first outer iteration.

That’s why Split in Batches works for you , it’s stateless, while Loop Over Items doesn’t handle nesting well.

Here’s what I’d recommend:

The cleanest approach is to move the inner loop logic to a sub-workflow. It keeps things clear and isolated, and you won’t run into state issues.

Alternatively, you could restructure your data so you only need one loop — for example, flatten your invoices and products before looping through them.

If you really need both loops in the same workflow:

There’s an advanced workaround using the Reset option. Go to your inner loop (loop_on_products), open Options → Reset, choose Expression, and try something like:

{{ $prevNode.name === 'get_products_by_invoice' }}

Just replace 'get_products_by_invoice' with whatever node actually feeds products into your inner loop.

What this does is tell n8n: “Hey, when new items arrive from that node, reset the inner loop and start fresh. But when the loop continues on its own Continue branch, don’t reset — otherwise you’ll get stuck in an infinite loop.”

This is a known workaround in the community (sometimes called the “classic nested loop fix”), but honestly, the sub-workflow approach tends to be cleaner and way less prone to weird bugs down the road.

Reference:
[Nested loops; Loop on loop; Loop inside loop]
[Loops/Sub-loop; Split in batch nested]

1 Like

thanks for details explanation and workaround. I have flatten my data. I go through your alternate solution in future.

1 Like