# Error-circular - where is this coming from?

**URL:** https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114
**Category:** General
**Created:** [21 January 2019 20:37 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114 "2019-01-21T20:37:23Z")
**Posts on this page:** 20
**Page:** 2

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [23 January 2019 08:03 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/21 "2019-01-23T08:03:25Z")

</div>

About using `context.myname` @knolleary said

> [@knolleary](#):
>
> It _is_ deprecated because anything stored that way will not get persisted.
> 
> However, it still has its uses - such as this precise scenario where it is meaningless to persist a timer id object.

I thought that deprecated meant that at some point in the future it will be removed and therefore it should not be used.  
A further question, am I right in thinking that if one asks for a local file store _and_ a memory store, that when using the memory store the operation using `context.set()` and specifying the memory store is identical to using `context.myname`?

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [23 January 2019 08:46 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/22 "2019-01-23T08:46:44Z")

</div>

@Andrei  
Right! the example is in the Wiki ([Fading](https://github.com/cflurin/node-red-contrib-dsm/wiki/Fading))

@hazymat  
The `Fading`example above can do more than you need, so I didn't mention it.  
But it can be simplified for your use case.

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [23 January 2019 09:02 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/23 "2019-01-23T09:02:34Z")

</div>

@Colin  
I'm surprised that you don't use the `contextStorage` property.  
This is one of the features I was waiting since I'm using Node-RED. I guess 80% or more running v0.19 or greater use it with the default `localfilesystem`.

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [23 January 2019 09:12 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/24 "2019-01-23T09:12:11Z")

</div>

@coliin

> is identical to using `context.myname` ?

no - that is why it is "deprecated". As this thread has shown using .set works by serialising the data. This is necessary if you want to store the data "offboard" eg in a file / database / over the network. Whereas context.myname can handle non-serialisable data like objects containing functions or circular references - and is ONLY held in memory.  
So in most cases it will appear the same to the user... but is NOT identical.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [23 January 2019 09:29 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/25 "2019-01-23T09:29:11Z")

</div>

> [@dceejay](#):
>
> .set works by serialising the data.

Has that always been the case? If so then the circular error seen is not inherent in storing timer id using `context.set` but must be something about this specific use case.  
Back on the deprecation of `context.myname`. If it has a useful purpose that is not covered by `context.set` then I would have thought it cannot be deprecated. Unless my understanding of deprecated is wrong (that it should not be used as it will be removed from node-RED at some point).

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [23 January 2019 09:37 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/26 "2019-01-23T09:37:31Z")

</div>

> [@cflurin](#):
>
> I'm surprised that you don't use the `contextStorage` property.

I use MQTT with retained topics for this. It has a number of advantages:

1. Any subscribers to the topic get notified when the value changes and can take action. This does not happen with persistent context variables.
2. The persistent values are available across systems. For example I have similar dashboards in a number of different node-red systems. They can all subscribe to the same topics on the same server (where appropriate) so that, for example, if I have a switch on the dashboard and I switch it on one system then that is immediately echoed on the dashboards on the other systems.
3. Automatic initialisation of dependent objects on re-deploy. If I redeploy node-RED then the switch mentioned above automatically gets initialised. To achieve that with context variables requires something like using inject nodes configured to inject the value at startup.

I am not saying there are no uses for persistent context, just that I have not found the need so far.

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [23 January 2019 09:41 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/27 "2019-01-23T09:41:29Z")

</div>

BTW assuming you have defined contextStorage like:

```auto
    contextStorage: {
        default: {
	          module:"localfilesystem"
        },
        memoryOnly: {
            module: "memory"
        }
    },

```

You can do it this way if you want to avoid `Error-circular`:

```auto
context.set('id', id, 'memoryOnly');
and
context.get('id', 'memoryOnly');

```

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [23 January 2019 09:43 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/28 "2019-01-23T09:43:21Z")

</div>

> [@Colin](#):
>
> Has that always been the case?

Yes. There is nothing in setTimeout that is circular - but the way he is calling his function from inside his function makes it so.

context is a javascript object - we can't remove it or stop people using it in normal javascript ways (such as adding a property) - but we can advise against using it if they want to be able to persist values when restarting Node-RED.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [23 January 2019 09:45 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/29 "2019-01-23T09:45:42Z")

</div>

> [@cflurin](#):
>
> You can do it this way if you want to avoid `Error-circular` :

Does that fix it for the users case? If so that appears to conflict with @dceejay's statement that context.set with memory store will still do the serialisation.

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [23 January 2019 09:52 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/30 "2019-01-23T09:52:16Z")

</div>

> [@Colin](#):
>
> Does that fix it for the users case?

I've tried several times and it seems to work.

---

<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: [23 January 2019 09:52 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/31 "2019-01-23T09:52:52Z")

</div>

> [@Colin](#):
>
> Back on the deprecation of `context.myname` . If it has a useful purpose that is not covered by `context.set` then I would have thought it cannot be deprecated. Unless my understanding of deprecated is wrong (that it should not be used as it will be removed from node-RED at some point).

Deprecated means you shouldn't use it as there's no guarantee it will be there in the future. But nor is it a guarantee that it'll be removed.

In this instance, the _only_ result of preventing a user from setting properties on the context object directly would be to break a lot of people's flows needlessly. There would be no benefit in doing that.

It was deprecated very early on in favour of context.set() because we did not want users to assume their flows would magically start persisting those values. That was long before we got into the detailed design and implementation work around persistent context.

During that work, it became clear there was still a role to play for setting `context.foo` directly - for volatile values that cannot be persisted, but have no need to be persisted. We just haven't spelt that out in the documentation.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [23 January 2019 10:02 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/32 "2019-01-23T10:02:32Z")

</div>

@dceejay, This seems to suggest that context.set of circular object with memory store is ok  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/5/5138d09fb5bb3460dc5df4705eecbc3832c6bf2b.png)

```auto
[{"id":"e5ef82be.d668c8","type":"function","z":"514a90a5.c7bae8","name":"Circular context set","func":"let a = { b: null };\nlet b = { a: a };\na.b = b;\ncontext.set(\"a\", a);\nmsg.payload = context.get(\"a\");\nreturn msg;","outputs":1,"noerr":0,"x":321.5,"y":358,"wires":[["3e4a4081.cbe08"]]},{"id":"70f2ea5b.d5a6e4","type":"inject","z":"514a90a5.c7bae8","name":"Tryit","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":129.5,"y":359,"wires":[["e5ef82be.d668c8"]]},{"id":"3e4a4081.cbe08","type":"debug","z":"514a90a5.c7bae8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":534,"y":357,"wires":[]}]

```

---

<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: [23 January 2019 10:17 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/33 "2019-01-23T10:17:06Z")

</div>

The in-memory store does not do any serialisation - it keeps the objects in memory, as-is. So you can throw any junk you want in there.

As soon as you switch the in-memory store for a file-based store, that junk will either get lost or cause errors.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [23 January 2019 10:23 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/34 "2019-01-23T10:23:49Z")

</div>

> [@knolleary](#):
>
> The in-memory store does not do any serialisation

OK, that is what I initially assumed, but when I asked @dceejay that very question he appeared to give a different answer.

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [23 January 2019 10:33 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/35 "2019-01-23T10:33:49Z")

</div>

IMHO as the `context.myname` is deprecated it'd be better to use:

```auto
context.set('id', id, 'memoryOnly');

```

---

<div class="post-metadata">

### Author: ![hazymat](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hazymat/32/108159_2.png) [@hazymat](https://discourse.nodered.org/u/hazymat)
#### Post date: [23 January 2019 10:46 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/36 "2019-01-23T10:46:13Z")

</div>

I'll try this later today when I get a chance to VPN home. Did you test it with my function, or with a different (test) function?

I don't fully understand everything in this thread, but it's fascinating nevertheless, and I can pick up various bits and pieces of things people say here and experiment myself...

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [23 January 2019 10:51 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/37 "2019-01-23T10:51:20Z")

</div>

> [@hazymat](#):
>
> Did you test it with my function, or with a different (test) function?

I modified you original function (and didn't change your "coding style"):

```auto
// Check for correct incoming values
if (!msg.reset &&
    (!msg.payload ||
     !msg.dimtime ||
     !msg.initialdelay)) {
    node.warn("Fader not correctly configured");
    return;
}

var thisnodeid = "fader_" + node.id;

// Get incoming values
var startval = Number(msg.payload); // just in case incoming was a string
var dimtime = msg.dimtime * 1000;
var initialdelay = msg.initialdelay * 1000;
var steptime = dimtime / startval;

// If we got a msg.reset, cancel timer, clear status,
// clear function from memory, and don't restart
if (msg.reset) {
    var id = context.get(thisnodeid, 'memoryOnly');
    clearTimeout(id);
    node.status({});
    context.set(thisnodeid,"", 'memoryOnly');
    return;
}

// if context.get('id') has an object, then it's running
// and if it's running then clear the timer, clear the memory,
// then continue (i.e. start over with new fader)
if (context.get('id') !== '') {
    var id = context.get(thisnodeid, 'memoryOnly');
    clearTimeout(id);
    node.status({});
    context.set(thisnodeid,"",'memoryOnly');
}

// Set initial light level
msg.payload = startval; // (use startval in case input was string)
node.send(msg);

var id = setTimeout(function(){
    var i = startval;
    function f() {
        if (i>0) {
            i--;
            msg.payload = i;
            node.send(msg);
            var fadetxt = "Fading " + (i*steptime/1000).toString() + "s, " + i.toString() + "/" + startval.toString();
            node.status({fill:"green", shape:"ring", text:fadetxt});
        } else {
            node.status({});
            context.set(thisnodeid,"", 'memoryOnly');
            return;
        }
        id = setTimeout( f, steptime );
        context.set(thisnodeid,id, 'memoryOnly');
    }
    f();
},initialdelay)
context.set(thisnodeid,id, 'memoryOnly');

node.status({fill:"blue", shape:"ring", text:"Delay " + msg.initialdelay.toString() + "s"});

```

Note: you need this setting in the settings.js:

```auto
    contextStorage: {
        default: {
	          module:"localfilesystem"
        },
        memoryOnly: {
            module: "memory"
        }
    },

```

---

<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: [23 January 2019 10:52 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/38 "2019-01-23T10:52:34Z")

</div>

> [@cflurin](#):
>
> Note: you need this setting in the settings.js:

If you use `context.thisnodeid` then there's absolutely no need to modify settings.js to get this to work.

Please reread what I said about the deprecation of this feature. We are _undeprecating_ it for this sort of use case.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [23 January 2019 10:58 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/39 "2019-01-23T10:58:13Z")

</div>

> [@knolleary](#):
>
> Please reread what I said about the deprecation of this feature. We are _undeprecating_ it for this sort of use case.

We are going round in circles here, if context.set used with memory storage is the same as context.myvar then it can stay deprecated.

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [23 January 2019 10:59 UTC](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114/40 "2019-01-23T10:59:16Z")

</div>

> [@knolleary](#):
>
> Please reread what I said about the deprecation of this feature. We are _undeprecating_ it for this sort of use case.

No need to reread it, I agree! but I suspect new Node-RED's users will face this "issue" in the future.

[Previous page](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114.md?page=1)

[Next page](https://discourse.nodered.org/t/error-circular-where-is-this-coming-from/7114.md?page=3)
