Switch node using dates reports ERROR: The value "undefined" is not a valid DateTime

I’m using a switch node to determine if the date of an object is more than 30 days old. The rest of the workflow executes as expected, but I get “ERROR: The value “undefined” is not a valid DateTime.” when the switch node is executed. Below is the node definition.

    {
  "parameters": {
    "dataType": "dateTime",
    "value1": "={{$node[\"Get Device IDs\"].json[\"results\"][0][\"last_contact_time\"]}}",
    "rules": {
      "rules": [
        {
          "operation": "before",
          "value2": "={{$node[\"Format Today's Date\"].json[\"today\"]}}"
        },
        {
          "value2": "={{$node[\"Format Today's Date\"].json[\"today\"]}}",
          "output": 1
        }
      ]
    }
  }

Any ideas on where I’m going wrong?

Hey @jesseharrismfi!

Welcome to the community :sparkling_heart:

Do you see the output in the Result section when you add the expression? Also, how many items are you passing? It is possible that you have multiple input items, but only a few of them contain the date field. If you can share your workflow and/or the outputs you get, it will help us debug and find a solution :slight_smile:

Yes, I see the expected result from the expression, the date from the appropriate field. I’m pulling down around 330 records at a time and I verified in the JSON data that each of the date fields I’m using is not null. Below is the sanitized workflow.

{
  "name": "Carbon Black - Decommissioned Machine Cleanup",
  "nodes": [
{
  "parameters": {},
  "name": "Start",
  "type": "n8n-nodes-base.start",
  "typeVersion": 1,
  "position": [
    270,
    160
  ]
},
{
  "parameters": {
    "triggerTimes": {
      "item": [
        {
          "mode": "everyHour",
          "minute": 15
        }
      ]
    }
  },
  "name": "Cron",
  "type": "n8n-nodes-base.cron",
  "typeVersion": 1,
  "position": [
    80,
    300
  ]
},
{
  "parameters": {
    "url": "https://<masked>/api/queries/30/results.csv?api_key=<masked>\n",
    "allowUnauthorizedCerts": true,
    "responseFormat": "file",
    "options": {},
    "headerParametersUi": {
      "parameter": []
    }
  },
  "name": "Pull list from Redash",
  "type": "n8n-nodes-base.httpRequest",
  "typeVersion": 1,
  "position": [
    560,
    300
  ],
  "notesInFlow": true,
  "notes": "Grab list of retired machines from Redash."
},
{
  "parameters": {
    "options": {
      "headerRow": true,
      "readAsString": true,
      "range": "A1:A100"
    }
  },
  "name": "Parse machine names",
  "type": "n8n-nodes-base.spreadsheetFile",
  "typeVersion": 1,
  "position": [
    740,
    300
  ]
},
{
  "parameters": {
    "authentication": "headerAuth",
    "requestMethod": "POST",
    "url": "https://defense-prod05.conferdeploy.net/appservices/v6/orgs/<masked>/devices/_search",
    "jsonParameters": true,
    "options": {},
    "bodyParametersJson": "={\n    \"query\": \"{{$node[\"Parse machine names\"].json[\"SystemName\"]}}\"\n}"
  },
  "name": "Get Device IDs",
  "type": "n8n-nodes-base.httpRequest",
  "typeVersion": 1,
  "position": [
    950,
    300
  ],
  "credentials": {
    "httpHeaderAuth": "Carbon Black Device Query"
  }
},
{
  "parameters": {
    "authentication": "headerAuth",
    "requestMethod": "POST",
    "url": "https://defense-prod05.conferdeploy.net/appservices/v6/orgs/<masked>/device_actions",
    "jsonParameters": true,
    "options": {},
    "bodyParametersJson": "={\n    \"action_type\": \"UNINSTALL_SENSOR\",\n    \"device_id\": [\"{{$json[\"deviceID\"]}}\"]\n}"
  },
  "name": "Deregister Endpoints",
  "type": "n8n-nodes-base.httpRequest",
  "typeVersion": 1,
  "position": [
    1480,
    190
  ],
  "credentials": {
    "httpHeaderAuth": "Carbon Black Deregister Endpoint"
  }
},
{
  "parameters": {
    "values": {
      "string": [
        {
          "name": "deviceID",
          "value": "={{$json[\"results\"][0][\"id\"]}}"
        }
      ]
    },
    "options": {}
  },
  "name": "Set",
  "type": "n8n-nodes-base.set",
  "typeVersion": 1,
  "position": [
    1280,
    190
  ]
},
{
  "parameters": {},
  "name": "NoOp",
  "type": "n8n-nodes-base.noOp",
  "typeVersion": 1,
  "position": [
    1450,
    450
  ]
},
{
  "parameters": {
    "functionCode": "var today = new Date();\nitems[0].json.date_today = new Date(new Date().setDate(today.getDate()-30));\n\nreturn items;"
  },
  "name": "Get Today's Date",
  "type": "n8n-nodes-base.function",
  "position": [
    220,
    300
  ],
  "typeVersion": 1
},
{
  "parameters": {
    "value": "={{$json[\"date_today\"]}}",
    "dataPropertyName": "today",
    "options": {}
  },
  "name": "Format Today's Date",
  "type": "n8n-nodes-base.dateTime",
  "typeVersion": 1,
  "position": [
    380,
    300
  ]
},
{
  "parameters": {
    "dataType": "dateTime",
    "value1": "={{$node[\"Get Device IDs\"].json[\"results\"][0][\"last_contact_time\"]}}",
    "rules": {
      "rules": [
        {
          "operation": "before",
          "value2": "={{$node[\"Format Today's Date\"].json[\"today\"]}}"
        },
        {
          "value2": "={{$node[\"Format Today's Date\"].json[\"today\"]}}",
          "output": 1
        }
      ]
    }
  },
  "name": "Validate Last Active",
  "type": "n8n-nodes-base.switch",
  "typeVersion": 1,
  "position": [
    1120,
    300
  ],
  "notes": "Because the Carbon Black API does a wildcard search in machine names, so when searching for PRVJSMITH, an inactive machine, you would also get PRVJSMITH01, an active machine. Double checking to make sure we only execute on inactive machines provides a failsafe for this edge case."
}
  ],
  "connections": {
"Cron": {
  "main": [
    [
      {
        "node": "Get Today's Date",
        "type": "main",
        "index": 0
      }
    ]
  ]
},
"Pull list from Redash": {
  "main": [
    [
      {
        "node": "Parse machine names",
        "type": "main",
        "index": 0
      }
    ]
  ]
},
"Parse machine names": {
  "main": [
    [
      {
        "node": "Get Device IDs",
        "type": "main",
        "index": 0
      }
    ]
  ]
},
"Get Device IDs": {
  "main": [
    [
      {
        "node": "Validate Last Active",
        "type": "main",
        "index": 0
      }
    ]
  ]
},
"Set": {
  "main": [
    [
      {
        "node": "Deregister Endpoints",
        "type": "main",
        "index": 0
      }
    ]
  ]
},
"Get Today's Date": {
  "main": [
    [
      {
        "node": "Format Today's Date",
        "type": "main",
        "index": 0
      }
    ]
  ]
},
"Format Today's Date": {
  "main": [
    [
      {
        "node": "Pull list from Redash",
        "type": "main",
        "index": 0
      }
    ]
  ]
},
"Validate Last Active": {
  "main": [
    [
      {
        "node": "Set",
        "type": "main",
        "index": 0
      }
    ],
    [
      {
        "node": "NoOp",
        "type": "main",
        "index": 0
      }
    ]
  ]
}
  },
  "active": false,
  "settings": {
"timezone": "America/Denver"
  },
  "id": "1"
}

Hey,

Can you please share the output you receive? You can mask all the sensitive data. Looking at the expression in the Value 1 field of the Switch node, I think the data structure is not correct. You might have to change the data structure that is compatible with n8n. However, without looking at the output it is difficult to debug.

I think I’ve tracked down the problem. If I use a ISO-8601 date hard-coded (e.g. 2021-05-03T21:15:30.634Z), it works. When I try to pull it from a node that generates the date in this format (e.g. {{new Date($node[“Get Today’s Date”].json[“date_today”]).toISOString()}}), it will fail after the first iteration. Any ideas on a cause for that?

Maybe the node Get Today’s Date contains only one item?

If that is the case then you have to change the part;
$node["Get Today’s Date"].json["date_today"]
to
$item(0).$node["Get Today’s Date"].json["date_today"]

That works for the date, but I think I’ve found the root issue. I’m pulling in a CSV of workstation names for decommissioning, and for some of them the alphanumeric name is getting changed to a numeric value. For example, the source CSV has a machine name of AUGPOWELL01, but the spreadsheet node shows 37104 in its place. Any explanation for this behavior?

Can you share the cvs file? At least with a few records so that I can reproduce the issue?

Unfortunately no. It contains too much proprietary company information. The workaround seems to be enabling the raw data option so that it won’t attempt to do any transforms.

bump having the same issue.
@jan It is as though the if statement is not evaluating the expression. This could explain allot of other bugs inside the if node. I have seen situations where 98 > 100 etc… “apples” != “apples” etc.

first is the real life use case, second is a simplified example, last if statement shows that the if block cannot evaluate expressions in that block i hard coded the evaluation of the prior block.

There seems to be a problem with Luxon dates. They seem not to be supported by the IF and Switch nodes. Created a ticket about that internally.

Anyway, there is actually no need for them in this case. If you remove the whole new DateTime.fromISO part it should work fine.

So replace for example:

{{new DateTime.fromISO($json["Modified_Time"])}}

with

{{$json["Modified_Time"]}}