Loop Node stopped working

Hi there,

  • Version 1.118.2

  • Database: Postgres

  • n8n EXECUTIONS_PROCESS setting: default

  • n8n selfhosted: yes

The loop in the workflow walks through a list of filtered categories and creates HTML based on the content in the code nodes. The workflow works as expected until the loop node.

These are the miniflux categories fed into the Loop node:

Expected

The loop should always walk through entries for all four categories. It does this if all categories have unread entries.

However….

Actual/Unecepcted

  • if a category does not contain entries, the loop stops unexpectedly
  • If all categories have at least 1 entry, all categories ware parsed, and 4 loop iterations are executed
    • Yet, not all entries are pulled (imho not related to the loop node, but the second miniflux node (get posts for category)

Questions
I’m a complete newbie, hence newbie questions:

  • how to ‘debug’ the loop node, i.e. how can I stop at each loop and observer the data? – if that makes sense.
  • The loop node is using default settings, i.e. BatchSize 1, do I miss any relevant settings?
  • And generally, is that approach a good practise? Or should use a different approach, e.g.
    • get all entries and and build the markup with one code node
    • use the new data tables feature
    • … anything I overlooked?
  • Do I actually need the loop?

Thanks in advance for your time and help!

I found the reason: whenever the returned set from miniflux was empty, the miniflux node did not send data, hence the code node was never activated and so the loop never ended.

fix:

  • got to the miniflux node settings and enable “Always Output data”

  • refactor the code node so that it catches the empty object and sends default data (e.g. “empty feed”)

Here’s the helper function to determine if the object sent by minflux is empty.

function isEmpty(entry) {
  for (const prop in entry.json) {
    if (Object.hasOwn(entry.json, prop)) {
      return false;
    }
  }
  return true;
}

const entries = $input.all()

// If there are no unread entries for this category, stop this branch of the loop
if (entries.length === 1 && isEmpty(entries[0])) {
  
  return [{ json: { yourdata } }]
} else {
  // go and work through the list of entries
}