# A strange problem on fs.stat usage inside function node

**URL:** https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202
**Category:** General
**Created:** [28 May 2022 22:44 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202 "2022-05-28T22:44:11Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![davidz](https://avatars.discourse-cdn.com/v4/letter/d/a88e57/32.png) [@davidz](https://discourse.nodered.org/u/davidz)
#### Post date: [28 May 2022 22:44 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202/1 "2022-05-28T22:44:11Z")

</div>

Run into a strange problem: Calling fs.stat() function inside Node-RED's function node, msg.payload can be updated correctly, depending on whether the file exists or does not exist. But the variable tt is undefined, instead of being 0 or 1. What could be the issue?

```auto
var tt;

fs.stat('/home/pi/testfile', function(err) {
    if (err) {
      msg.payload = false // testfile does not exist
      tt=0;
    } else {
      msg.payload = true // testfile exists
      tt=1;
    }
});
msg.tt=tt; // tt is always undefined 
return msg;

```

Please see the debug output:

 ![output](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/4/04ed86a39146b5b5caa0337022e0f08e6b3ce101.jpeg)

The test flow is here:

```auto
[{"id":"d91f5f9882284a25","type":"function","z":"d3c8b30753c78d12","name":"Tests","func":"var tt;\n\nfs.stat('/home/pi/testfile', function(err) {\n if (err) {\n msg.payload = false // testfile does not exist\n tt=0;\n } else {\n msg.payload = true // testfile exists\n tt=1;\n }\n});\nmsg.tt=tt;\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"fs","module":"fs"}],"x":1050,"y":1440,"wires":[["161e8c033aaf1a33"]]},{"id":"67ccbdbb6a93218e","type":"inject","z":"d3c8b30753c78d12","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":900,"y":1440,"wires":[["d91f5f9882284a25"]]},{"id":"161e8c033aaf1a33","type":"debug","z":"d3c8b30753c78d12","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1230,"y":1440,"wires":[]}]

```

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [28 May 2022 22:51 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202/2 "2022-05-28T22:51:24Z")

</div>

I think you will find that `fs.stat` is an asynchronous function. So the `msg.tt=tt` line is executed immediately and only later is the msg.payload set. If you are seeing the correct output after the node, that is pure coincidence of timing and due to JavaScript passing variables by reference so that the msg object gets updated before you actually reference it in a later node.

Put the final 2 lines of your function node inside the stat callback function and everything should work correctly.

---

<div class="post-metadata">

### Author: ![davidz](https://avatars.discourse-cdn.com/v4/letter/d/a88e57/32.png) [@davidz](https://discourse.nodered.org/u/davidz)
#### Post date: [28 May 2022 22:57 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202/3 "2022-05-28T22:57:12Z")

</div>

Yes you are correct.

But if putting final two lines of the function node inside the stat callback function, then there is no output returned from the debug node. It caused strange behavior from the console output instead.

Putting "msg.tt=tt " inside works. What could be the reason?  
The following is the working code:

```auto
fs.stat('/home/pi/testfile', function(err) {
    if (err) {
      msg.payload = false // testfile does not exist
      msg.tt=0;
    } else {
      msg.payload = true // testfile exists
      msg.tt=1;
    }
});

return msg;

```

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [28 May 2022 23:00 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202/4 "2022-05-28T23:00:44Z")

</div>

You might want to do some reading up on asynchronous coding in node.js.

The function attached as a callback to the stat call is run when stat actually returns something useful. Anything outside of that function and after it in the code will run immediately that the function node runs.

```auto
fs.stat('/home/pi/testfile', function(err) {
    if (err) {
      msg.payload = false // testfile does not exist
      msg.tt=0;
    } else {
      msg.payload = true // testfile exists
      msg.tt=1;
    }
    node.send(msg);
});

node.warn('Ooh! This is output BEFORE the actual message')

```

Note that while node-red _appears_ to be passing messages around - it really ISN'T! It is passing references to a msg object. That means that the content of the msg object can continue to change - sometimes unexpectedly - due to ongoing async code finally returning something.

Putting the `node.send(msg)` inside the callback function ensures that it will only output a msg when there is a valid response.

---

<div class="post-metadata">

### Author: ![davidz](https://avatars.discourse-cdn.com/v4/letter/d/a88e57/32.png) [@davidz](https://discourse.nodered.org/u/davidz)
#### Post date: [28 May 2022 23:10 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202/5 "2022-05-28T23:10:46Z")

</div>

That makes sense.

Can we use await method to wait until the fs.stat finishes processing?  
This way, we can put return msg outside the function.

How to do it in the function node?

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [28 May 2022 23:33 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202/6 "2022-05-28T23:33:08Z")

</div>

The docs explain how to send messages asynchronously: [Writing Functions : Node-RED](https://nodered.org/docs/user-guide/writing-functions#sending-messages-asynchronously)

You cannot use `return` to do that inside an async callback.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [29 May 2022 00:08 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202/7 "2022-05-29T00:08:37Z")

</div>

My bad, corrected the post to `node.send`

---

<div class="post-metadata">

### Author: ![davidz](https://avatars.discourse-cdn.com/v4/letter/d/a88e57/32.png) [@davidz](https://discourse.nodered.org/u/davidz)
#### Post date: [29 May 2022 00:40 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202/8 "2022-05-29T00:40:25Z")

</div>

@knolleary Thanks Nick. It would be great to have more examples along with the description.

@TotallyInformation Yes I was about to say the same thing after reading through the description.  
Need to use Node.send, otherwise there could be unexpected behavior.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [12 June 2022 00:40 UTC](https://discourse.nodered.org/t/a-strange-problem-on-fs-stat-usage-inside-function-node/63202/9 "2022-06-12T00:40:45Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
