Required switch logic not working

Describe the problem/error/question

Hello, I get crazy while trying to establish an IF or Switch node. What I try to do is: use this route if the webhook is given an attachment and if there is no attachment, use the other or fallback route. But it alwayss takes the one for “with attachment”. It is annoying and I have no other idea than asking you gyus. Hope you can assist me with this.

What is the error message (if any)?

There is no error message, but it always takes output 0. Expected behaviour is, that it should different route or fallback, when it comes to an event without attachment.

Please share your workflow


(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)

Share the output returned by the last node

Information on your n8n setup

  • n8n version: 2.8.4 (self hosted, community version)
  • Database (default: SQLite): default
  • n8n EXECUTIONS_PROCESS setting (default: own, main): ?
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker
  • Operating system: debian 12
1 Like

Hi @nephilim

using .toString().trim() is actually what’s breaking it. forcing that on an empty field tricks n8n into thinking there is valid data there.

change your routing rule to just ={{ $json.body.attachment }} and keep the condition set to is not empty.

Can you share a screenshot of your IF/Switch node config and maybe the output of the webhook node when it receives a request without an attachment? Hard to tell what’s going wrong without seeing what expression you’re using to check for the attachment.

Unfortunately this doens’t work either. :frowning: Still the same flow…

Input from Webhook:

[
  
{
  
  
"headers": {
  
  
  
"host": "sub.domain.com",
  
  
  
"x-forwarded-scheme": "https",
  
  
  
"x-forwarded-proto": "https",
  
  
  
"x-forwarded-for": "64.227.21.251",
  
  
  
"x-real-ip": "64.227.21.251",
  
  
  
"content-length": "159",
  
  
  
"accept-encoding": "deflate, gzip",
  
  
  
"accept": "application/json",
  
  
  
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:148.0) Gecko/20100101 Firefox/148.0",
  
  
  
"content-type": "application/json"
  
  
},
  
  
"params": {
  
  
},
  
  
"query": {
  
  
},
  
  
"body": {
  
  
  
"from": "[email protected]",
  
  
  
"to": "[email protected]",
  
  
  
"subject": "Test OHNE Attachment",
  
  
  
"bodyHtml": "<p>Hallo Carsten,<br>Test mit Datei.</p>"
  
  
},
  
  
"webhookUrl": "https://sub.domain.com/webhook-test/95e05ec5-f600-494d-8e8a-0aacc04fb46a",
  
  
"executionMode": "test"
  
}
]

Output Switch:

[
  
{
  
  
"headers": {
  
  
  
"host": "sub.domain.com",
  
  
  
"x-forwarded-scheme": "https",
  
  
  
"x-forwarded-proto": "https",
  
  
  
"x-forwarded-for": "64.227.21.251",
  
  
  
"x-real-ip": "64.227.21.251",
  
  
  
"content-length": "159",
  
  
  
"accept-encoding": "deflate, gzip",
  
  
  
"accept": "application/json",
  
  
  
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:148.0) Gecko/20100101 Firefox/148.0",
  
  
  
"content-type": "application/json"
  
  
},
  
  
"params": {
  
  
},
  
  
"query": {
  
  
},
  
  
"body": {
  
  
  
"from": "[email protected]",
  
  
  
"to": "[email protected]",
  
  
  
"subject": "Test OHNE Attachment",
  
  
  
"bodyHtml": "<p>Hallo Carsten,<br>Test mit Datei.</p>"
  
  
},
  
  
"webhookUrl": "https://sub.domain.com/webhook-test/95e05ec5-f600-494d-8e8a-0aacc04fb46a",
  
  
"executionMode": "test"
  
}
]

Hope, this helps to clearify the issue.

Thank you so mmuch for your assistance.

Kind regards

//neph

1 Like

@nephilim
the attachment field isn’t just empty—it’s completely missing from the $json.body object.

try this:

  • open your Switch node.
  • change the data type for the rule from String to Boolean.
  • set the value to this expression: ={{ $json.body.attachment ? true : false }}
  • set the condition to is true.

now, n8n is forced into a strict yes-or-no decision. if the attachment field exists and has data, the expression outputs true and it routes to Output 0. if the field is completely missing like in your payload, it outputs false and instantly drops into the Fallback route.

Yeah so looking at your webhook data the attachment field isn’t just empty, it’s completely absent from the body object which is why “is not empty” on a string check keeps failing in weird ways. Try using ={{ $json.body.hasOwnProperty('attachment') }} as a Boolean condition set to “is true”, that way you’re explicitly checking whether the field exists at all rather than trying to evaluate its contents.

I tried as recommended with “={{ $json.body.attachment ? true : false }}" and "={{ $json.body.hasOwnProperty(‘attachment’) }}”. In both the cases it comes back with the message in the right up corner. A test run took the wrong route again. Sorry, I am absolute new in this topic.

What else am I doing wrong?

The error message is actually telling you exactly what to do — toggle on “Convert types where required” in the Switch node settings, that way n8n will convert the string “false” into an actual boolean and the condition will work properly.

Turn on the “Convert types where required” toggle in your Switch node, that error is telling you the expression result is coming back as a string instead of a boolean and flipping that switch will fix it.

That error is telling you exactly what to fix actually, the expression is returning the string “false” instead of a boolean. Just toggle on “Convert types where required” in your Switch node settings and it should work with either expression.

And I tested it this way. It takes the wrong route again:

@nephilim
Your setup isn’t broken. You just tested it with an email that doesn’t have an attachment.

Because the attachment field is missing (your test subject even says “Test OHNE Attachment”), the expression equals false. So, it goes to the Fallback route exactly like it’s supposed to.

Run a new test using an email that actually has a file attached. It will route to Output 0 perfectly.

It still fails, if no attachmend is part of the webhook:

The one with attachment, runs through as expected:

Maybe this is the wrong setup for this taskk? Is there some other way I could use to get this use case running properly?

@nephilim
drop an If node in there instead of the switch. set the condition to String, value 1 to ={{ $json.body.attachment || '' }} and the operator to is not empty.

that || '' bit is the trick. if the webhook completely drops the attachment field, n8n instantly forces it into an empty string. the If node catches it, sees it’s empty, and drops the run perfectly down the false branch to your text-only email.

Hi, @nephilim
@A_A4 Gives you a very good suggestion, it’s for the case JSON attachments array to boolean.
You can combine JSON or Binary as following:

 {{ ($json["attachments"] && $json["attachments"].length > 0) || (Object.keys($binary || {}).length > 0) }}

Unfortunately the same behaviour as previosly. Might it be possible that version 2.8.4 is buggy when it comes to the if and switch node? I don’t believe it, but… Well, any further assistance is highly appreciated.

Kind regards

Which operator shall I use when it comes to the boolean choice?

@nephilim
I highly doubt it’s a bug in 2.8.4. The If and Switch nodes are heavily relied on, so a bug there would be pretty widely reported.It’s more likely that the expression engine is tripping up, or the webhook is sending an “empty” value that the If node doesn’t natively recognize as empty.

Drop this into a Code node right after your webhook. It forces a hard true or false variable that you can reliably route off of:

const data = $input.first().json;

// checks if the attachment field exists, isn't null, and isn't totally empty
const hasAttachment = !!(
  data?.body?.attachment && 
  data.body.attachment !== 'null' && 
  Object.keys(data.body.attachment).length > 0
);

return {
  json: {
    ...data,
    has_real_attachment: hasAttachment
  }
};

After that, just hook up your If node and set it to check if the boolean has_real_attachment is true

1 Like