n8n logon8n Automation Hub
Debugging notes

n8n's Own Validator Told Me to "Fix" a Workflow That Wasn't Broken

Debugging notes · n8n workflow · September 9, 2026 · Updated October 13, 2026

A workflow validator flagged an IF node's wiring as incorrect and handed over a specific, confident fix. The fix would have inverted a working retry-versus-give-up branch — because the validator was pattern-matching on node names, not reading what the condition actually meant.

Workflow at a glance
  1. An IF node named "IF - Attempts Exceeded" checks a single condition: attempt >= 4
  2. When TRUE (attempts really are exhausted), it routes to a Telegram failure alert and a Sheets row reset — give up and let a human know
  3. When FALSE (still under the limit), it routes to an "Increment Attempt" node that loops back to retry
  4. The validator flagged this as "incorrect error output configuration," because the nodes wired to the TRUE branch have names like "Telegram - Render Failed" and "Reset Topic On Failure" — names that look like error handlers
  5. Its suggested fix: move those nodes to the FALSE branch instead, and add onError: continueErrorOutput to the IF node
  6. Applying that fix literally would have made the failure-and-reset path fire on every normal retry attempt, and made the real "give up after 4 tries" case do nothing at all

A confident, specific, wrong suggestion

The validator didn't hedge. Its output included a full before/after code comparison, labeled INCORRECT and CORRECT, plus the exact operation needed to fix it: move the "Telegram - Render Failed" and "Reset Topic On Failure" nodes from the IF node's first output array to its second, and add an onError property. That's a level of specificity that invites trust — it reads like a tool that has actually inspected the logic and knows what's wrong, not a generic linter warning.

What the validator is actually pattern-matching on

The heuristic behind this message treats a node's two outputs as if they always mean "success" and "error" — a convention that's real and correct for a node's own onError: continueErrorOutput output, where output 0 genuinely is the success path and output 1 genuinely is the error path. A plain IF node's two outputs don't mean that at all; they mean "condition true" and "condition false," and which one represents success or failure depends entirely on what the condition checks and how the workflow's author decided to route each branch. The validator appears to guess at this by scanning the names of the nodes connected to each branch — seeing "Failed" and "Reset ... Failure" downstream of output 0 was apparently enough to conclude output 0 must be a wrongly-placed error path.

Why the guess was backwards here

The actual condition is attempt >= 4. TRUE means the retry budget is exhausted — that is the failure case, and routing it to a Telegram alert plus a Sheets reset is exactly correct, not a mistake to be swapped. FALSE means there's still budget left, and that path correctly goes to "Increment Attempt" to try again. The validator's proposed fix would have swapped these: the failure-notification path would fire on output 1 (FALSE, meaning every single under-the-limit retry) instead of output 0 (TRUE, meaning genuinely out of retries), while the real exhausted-retries case would fall through to output 0 with nothing wired to it at all. The workflow would have gone from "alert only after 4 real failures" to "alert on every retry, and never actually alert when retries run out" — worse in both directions at once.

How this almost went unnoticed

The fix was applied once, exactly as suggested, and the workflow still validated cleanly afterward — a swapped IF branch is structurally valid, it's just semantically backwards, and structural validation has no way to know that. The only thing that caught it was going back to read the IF node's actual condition before trusting the change, rather than trusting the validator's own before/after framing of what "correct" meant. Re-reading it took under a minute; not doing so would have shipped a workflow that pages someone on every normal retry and stays silent the one time it's actually supposed to.

The generalizable rule

A validator's "incorrect error output configuration" message on a plain IF node is worth treating as a hypothesis, not a verdict — especially when it's inferring intent from node names rather than from the condition's actual logic. Before applying a suggested branch swap on any IF node, read what the condition checks and confirm, independently, which branch is actually supposed to represent the failure case. If the current wiring already matches that, the validator's pattern-matched guess is a false positive, and the real fix is to leave it alone.

IF outputs versus error outputs

IF node outputsError output (On Error: Continue using error output)
Output 0Condition is trueSuccess: items the node processed normally
Output 1Condition is falseError: items that failed
Meaning decided byThe condition you wroten8n

A validator that applies the right-hand column to an IF node will be wrong whenever the condition describes a failure, such as "attempts exceeded" or "status is error". In those workflows, true is the failure branch, and that is correct.

Naming conditions so the next reader can't misread them

Most of the confusion here came from a condition whose true branch is the bad case. Some ways to make that obvious to people and tools alike:

Testing that the branches really do what the names say

Structure validation can't tell a correct branch from a swapped one. A test can. For this loop the quickest one is to run the workflow once with the attempt limit set to 1: the very first failed poll must go down the give-up path, send the alert and reset the topic. If it loops instead, the branches are swapped. Afterwards set the limit back, and confirm that by reading the node back, not from memory.

The general rule I follow now: a validator's suggestion that changes behaviour, rather than syntax, gets applied only after I can say in one sentence why the current behaviour is wrong.

Frequently asked questions

Is n8n's 'incorrect error output configuration' warning always right?

No. On a plain IF node the two outputs mean true and false, not success and error. If the condition describes a failure, the true branch is correctly the failure path.

How do the outputs of an IF node differ from an error output?

An IF node's outputs depend on the condition you wrote. An error output, enabled with On Error: Continue (using error output), always sends failed items to the second output.

How do I test which branch a retry loop takes?

Temporarily set the attempt limit to 1 and run the workflow. The first failure must take the give-up path. Restore the limit afterwards and read the node back to confirm.

Does a workflow that validates cleanly behave correctly?

Not necessarily. Validation checks structure. Swapped branches are structurally valid and only show up in a test run.

Not sure whether a validation warning is a real bug or a false positive?

I debug production n8n workflows for a living, including telling apart the warnings worth acting on from the ones that would make things worse.