Error importing a flow

OK, so this code is AI generated so take with a generous pinch of salt.

However, on import, it generates a node marked as invalid but with no way to fix the issue! It is the Wait node that has the error. Nothing is shown in the log.

I've never seen this before and I don't think it should ever happen, importing a node with no way to fix an error.

Incidentally, I can manually re-create the delay node with exactly the same settings with no error.

[
    {
        "id": "tab_downloads",
        "type": "tab",
        "label": "Downloads Manager",
        "disabled": false
    },
    {
        "id": "watch",
        "type": "watch",
        "z": "tab_downloads",
        "name": "Watch Downloads",
        "files": "C:\\Users\\YOUR_USERNAME\\Downloads",
        "recursive": false,
        "x": 160,
        "y": 80,
        "wires": [
            [
                "filter"
            ]
        ]
    },
    {
        "id": "filter",
        "type": "function",
        "z": "tab_downloads",
        "name": "Ignore temp files",
        "func": "const path = require('path');\n\nconst file = msg.payload;\nconst ext = path.extname(file).toLowerCase();\n\nif (ext === '.crdownload' || ext === '.tmp') {\n    return null;\n}\n\nreturn msg;",
        "outputs": 1,
        "x": 390,
        "y": 80,
        "wires": [
            [
                "delay"
            ]
        ]
    },
    {
        "id": "delay",
        "type": "delay",
        "z": "tab_downloads",
        "name": "Wait 5 seconds",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "x": 610,
        "y": 80,
        "wires": [
            [
                "moveImage"
            ]
        ]
    },
    {
        "id": "moveImage",
        "type": "function",
        "z": "tab_downloads",
        "name": "Move images",
        "func": "const fs = require('fs');\nconst path = require('path');\n\nconst file = msg.payload;\nconst ext = path.extname(file).toLowerCase();\n\nconst images = [\n'.jpg','.jpeg','.png','.gif','.bmp','.webp','.tif','.tiff','.svg','.heic','.avif'\n];\n\nif (!images.includes(ext)) {\n    return null;\n}\n\nconst dir = path.dirname(file);\nconst targetDir = path.join(dir,'images');\n\nif (!fs.existsSync(targetDir)) {\n    fs.mkdirSync(targetDir,{recursive:true});\n}\n\nconst dest = path.join(targetDir,path.basename(file));\n\ntry {\n    fs.renameSync(file,dest);\n    node.status({fill:'green',shape:'dot',text:path.basename(file)});\n}\ncatch(err){\n    node.error(err,msg);\n}\n\nreturn null;",
        "outputs": 0,
        "x": 820,
        "y": 80,
        "wires": []
    },
    {
        "id": "injectHourly",
        "type": "inject",
        "z": "tab_downloads",
        "name": "Hourly",
        "props": [],
        "repeat": "3600",
        "once": true,
        "onceDelay": "5",
        "x": 140,
        "y": 220,
        "wires": [
            [
                "archiveOld"
            ]
        ]
    },
    {
        "id": "archiveOld",
        "type": "function",
        "z": "tab_downloads",
        "name": "Archive files >6 months",
        "func": "const fs = require('fs');\nconst path = require('path');\n\nconst downloadDir='C:\\\\Users\\\\YOUR_USERNAME\\\\Downloads';\nconst archiveDir=path.join(downloadDir,'archive');\n\nif(!fs.existsSync(archiveDir))\n    fs.mkdirSync(archiveDir,{recursive:true});\n\nconst cutoff=Date.now()-183*24*60*60*1000;\n\nfor(const item of fs.readdirSync(downloadDir)){\n\n    if(item==='archive' || item==='images')\n        continue;\n\n    const full=path.join(downloadDir,item);\n\n    let stat;\n\n    try{\n        stat=fs.statSync(full);\n    }\n    catch(e){\n        continue;\n    }\n\n    if(stat.isDirectory())\n        continue;\n\n    if(stat.mtimeMs<cutoff){\n        try{\n            fs.renameSync(full,path.join(archiveDir,item));\n        }\n        catch(err){\n            node.warn(err.message);\n        }\n    }\n}\n\nreturn null;",
        "outputs": 0,
        "x": 410,
        "y": 220,
        "wires": []
    }
]

All three of your function nodes contain require which as I understand it is incorrect in a Node-red function, so an iffy delay seems to be the least of your problems :laughing:

I wonder if these lines are somehow messing up the editor's error checking.

Did I not imply that the code wasn't to be trusted? That isn't the issue, the flow certainly cannot run as-is because of several faults in all of the function nodes. These issues are not impacting the delay node error, I've checked and already corrected all of the function nodes.

The issue is being able to import a flow containing a node that cannot be fixed.

Yes you did and I apologise if you thought I had not noticed.

I just wondered if the delay node would still be flagged invalid if there were no issues with the functions.
Or putting it another way, if the delay node's flows.json entry is in any way different from a manually created delay node.

Here they are:

[
    {
        "id": "delay",
        "type": "delay",
        "z": "tab_downloads",
        "name": "Wait 5 seconds.",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "",
        "nbRateUnits": "",
        "randomFirst": "",
        "randomLast": "",
        "randomUnits": "seconds",
        "allowrate": false,
        "outputs": 1,
        "x": 610,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "64d8bfea635c913e",
        "type": "delay",
        "z": "tab_downloads",
        "name": "Wait 5 seconds",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 620,
        "y": 140,
        "wires": [
            [
                "2ebc425b3dc5c288"
            ]
        ]
    }
]

THe 2nd entry is the manually added correct one.

Any differences should be dealt with by the node so there is possible a small bug in the delay node.

Quite a few differences there.

It looks like you either need a value for nbRateUnits or for randomFirst and randomLast.
I wonder what those attributes do.

It's hardly up to the node to handle any bad imports. If only we could educate chatgpt about the ways it borks Node-red code. :thinking:

I think the point is that it should be possible, by opening it and entering valid data into all the fields, to get it into a good state.

I’m afraid I disagree. I imported something that cannot be fixed without manually hacking the flow file. That is totally against the concepts of node-red.

The node is absolutely responsible for ensuring that it can be made valid.