Possible bug: IF node always returns true with complex JS condition

Describe the problem/error/question

When using an IF node with a more complex JavaScript expression (inside ={{ }}), the node always returns true, even when the expression evaluates to false.

It seems like the IF node misinterprets the result of the expression and passes the data through the true output regardless of the actual boolean result.

What is the error message (if any)?

There is no error message. But the logic of the IF node behaves incorrectly — returning true when it should be false.

Please share your workflow

Share the output returned by the last node

The output of the IF node is always sent to the true branch, even though the expression is false. I verified that the return value of the expression is actually false using logging/debug output.

I have a custom expression inside the IF node that returns false, and I’m explicitly comparing it to true. However, the node still routes to the “true” output.

{{ 
  (() => {
    const repeat = $json.Repeat;
    const now = new Date();
    const ms30min = 1800000;

    const days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
    
    return repeat
      .split(',')
      .map(s => s.trim())
      .some(timeStr => {
        const [weekday, time, meridian] = timeStr.split(' ');
        if (!weekday || !time || !meridian) return false;

        const [hourStr, minStr] = time.split(':');
        let hour = parseInt(hourStr, 10);
        if (meridian.toUpperCase() === 'PM' && hour !== 12) hour += 12;
        if (meridian.toUpperCase() === 'AM' && hour === 12) hour = 0;

        const target = new Date(now);
        const targetDay = days.indexOf(weekday);
        const currentDay = now.getDay();
        const offset = (targetDay - currentDay + 7) % 7;
        target.setDate(now.getDate() + offset);
        target.setHours(hour, parseInt(minStr), 0, 0);

        const diff = target - now;
        return diff > 0 && diff <= ms30min;
      });
  })()
}}

Information on my n8n setup

  • n8n version: 1.93.0
  • Database (default: SQLite): default (SQLite)
  • n8n EXECUTIONS_PROCESS setting (default: own, main): own
  • Running n8n via (Docker, npm, n8n cloud, desktop app): desktop app
  • Operating system: macOS (Apple Silicon)

Just a thought, I see that the input is “Repeat”: “Sunday 8:00 PM”, but then you .split(','), could this have anything to do with the issue, given there is no , in the input? Say, if you add the comma, would it start working the way you expect it to?

UPD:
or you expect the time to come in the format where there can be more than one? Something like “Sunday 8:00 PM, Monday 1:00 PM”?

UPD2:
if the idea behind the code is to see if the time is within the next 30 minutes and you always assume that the input time is in the future, would something like this do:

{{ 
  (() => {

    const dtStr = $json.Repeat;
    const ms30min = 1800000;

    let dt = dtStr.toDateTime('cccc hh:mm a');

    if (dt < $now) {
      dt = dt.plus(7, 'days');
    }
    return (dt - $now) < ms30min;
  })()
}}

Thanks for the suggestion!

  • When the expression returns false, the value is shown correctly in the result — but the node routes it to the **true output`, which is clearly a bug.

So the issue doesn’t seem to be in the logic of the expression itself, but rather how the IF node interprets or receives the result.

Context of my expression

My original code is designed to evaluate whether the current time is within 30 minutes of any scheduled time listed in a comma-separated string.
That string can include multiple entries like:

"Sunday 8:00 PM, Monday 9:30 AM, Friday 1:15 PM"

The logic:

  • Parses each entry
  • Converts it into a future Date
  • Compares how close it is to the current time (within 30 minutes)

If any match is found, it returns true.

The expression returns correct values during testing, but the IF node doesn’t route correctly based on those values.

I’ve attached detailed screenshots showing the expression, its result, and the wrong routing by the IF node:

:paperclip: (see screenshot below)


The result is false.

the comparison was with true, but went to the true line

:warning: Strange type coercion error

Another oddity:
Even though my expression returns a boolean, the IF node throws a type error:

Wrong type: 'false ' is a string but was expecting a boolean

This only goes away if I turn on “Convert types where required”. Even the use of.toBoolean() doesn’t work

  1. My expression result (false) being misrouted to the true path
  2. The type error with "false" being treated as a string

I have the same code now, but it doesn’t get an error on types. I don’t get it. :see_no_evil_monkey:

I previously had issues with using dates in the expressions, and specifically where the quick expression evaluation returns one value while actually executing it yield a different result. I was suggested using $now and $today as well as embedded helper functions around these, instead of trying to build luxon objects myself. In your specific case I found it easier to parse the “time” instead of splitting it into chunks, the only thing (as you see in the example I provided earlier) that I had to dance around was that parsing without date assumes that day of week always belong to current week, instead of the “next occurrence of that day of week” that you are going for. Anyway, there obviously something going on with dates and expression evaluation, I agree.

So the problem is not in the node, but in the dates and expression evaluation itself.
I wonder if it’s possible to file a bug report on this forum?

I think you can create one here.

1 Like

Thank you, I’ll do it.