# Write to client memory tag fails in tag event, yet succeeds in client timer event

**URL:** <https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [November 19, 2017, 3:57am UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048 "2017-11-19T03:57:54Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![YouCanCallMeGeorge](https://avatars.discourse-cdn.com/v4/letter/y/76d3ee/32.png) [@YouCanCallMeGeorge](https://forum.inductiveautomation.com/u/YouCanCallMeGeorge)\
**Post date:** [November 19, 2017, 3:57am UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/1 "2017-11-19T03:57:54Z")

</div>

I can write to a client memory tag from a client timer script, but not from the value-changed script for a tag.

Scenario:  
A fresh install of Ignition 7.9.5, with one simple project.  
A client timer script executes at 2 second intervals. (Was 1 second intervals for a while.)  
The timer script:  
-- Increments GenericSimulator.WriteableInteger1, so I know the timer script is running.  
-- Toggles GenericSimulator.WriteableBoolean1.  
-- Optionally toggles client string tag Info.  
The write to the Info tag always succeeds.

The value-changed script in GenericSimulator.WriteableBoolean1:  
-- Toggles GenericSimulator.WriteableBoolean2, so I know the WriteableBoolean1 script is running.  
-- Optionally toggles client string tag Info.  
The write to the Info tag never succeeds. There is no mention of the write in the wrapper log.

It is the same line of code in the two scripts.  
I use GenericSimulator.WriteableInteger2 to determine which script writes to the Info tag, so there is no contention. (I also ran the test by alternately disabling the scripts, with unconditional writes; same result.)

**Why would the same line of code work in the client timer script, and fail in the tag value-changed script?**

Separately, and seemingly unrelated, the wrapper log has this entry at one second intervals:  
-- Created auto-backup of internal database "config.idb" in 893 ms

**This is the code in the timer script:**  
iValue1 = system.tag.read('WriteableInteger1').value  
system.tag.write('WriteableInteger1', iValue1 + 1)

iValue2 = system.tag.read('WriteableInteger2').value

if system.tag.read("WriteableBoolean1").value:  
system.tag.write("WriteableBoolean1", False)  
if iValue2 == 1:  
system.tag.write("[Client]Status/Info", "False")  
else:  
system.tag.write("WriteableBoolean1", True)  
if iValue2 == 1:  
system.tag.write("[Client]Status/Info", "True")

**This is the code in the value-changed script for GenericSimulator.WriteableBoolean1:**  
iValue2 = system.tag.read('WriteableInteger2').value

```
if currentValue.value:
	system.tag.write("WriteableBoolean2", True)
	if iValue2 == 0:
		system.tag.write("[Client]Status/Info", "True")
else:
	system.tag.write("WriteableBoolean2", False)
	if iValue2 == 0:
		system.tag.write("[Client]Status/Info", "False")

```

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [November 19, 2017, 1:55pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/2 "2017-11-19T13:55:04Z")

</div>

Tags and tag value change scripts all live and execute in the gateway scope.

Your client tag only exists in the client, so you can only interact with it from the timer script running in the client.

---

<div class="post-metadata">

**Author:** ![YouCanCallMeGeorge](https://avatars.discourse-cdn.com/v4/letter/y/76d3ee/32.png) [@YouCanCallMeGeorge](https://forum.inductiveautomation.com/u/YouCanCallMeGeorge)\
**Post date:** [November 19, 2017, 7:51pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/3 "2017-11-19T19:51:53Z")

</div>

Interesting.  
I’ll need to adjust my thinking about the interaction between tags and project.  
First thought is to use gateway scoped memory tags.  
I see that gateway tags are shared among all clients.  
For tags that I want to protect, can I use roles restrict access to a certain project? (A mostly rhetorical question at this point; I haven’t read that section in the manual yet.)

Surprisingly, I have the same problem with an INSERT into my database. The prepared statement method works in the client timer script, but not in the OPC tag value-changed script. Surprising because the database connection is in the gateway.

(Thanks for answering on the weekend.)

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [November 20, 2017, 12:04am UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/4 "2017-11-20T00:04:42Z")

</div>

> [@YouCanCallMeGeorge](#):
>
> Surprising because the database connection is in the gateway.

Tag events, as part of a tag, do not belong to any project, and so have no "default database". All database operations in a global gateway context must specify which database connection to use.  
There are _ **three** _ contexts that a programmer must consider when using Ignition:

1. Client/designer context. Client tags, global jython variables, windows, and component all exist independently in each client. Gateway tags can trigger project-specific client events, which can use both project.\* and shared.\* scripts. Database operations use the project's default connection if none specified, and gateway tag operations use the project's default provider.
2. Gateway project context. Project-specific gateway events and transaction groups exist here. Client tags, windows, and components do not exist. Tag change scripts and other events in this context can use both project.\* and shared.\* scripts. Database operations in these scripts use the project's default connection if none specified, and gateway tag operations use the project's default provider.
3. Gateway global aka shared context. Tag events exist here. Client tags, windows, and components do not exist. Only shared.\* scripts are accessible. All database operations must specify a connection. All other tag operations must specify a provider.

---

<div class="post-metadata">

**Author:** ![YouCanCallMeGeorge](https://avatars.discourse-cdn.com/v4/letter/y/76d3ee/32.png) [@YouCanCallMeGeorge](https://forum.inductiveautomation.com/u/YouCanCallMeGeorge)\
**Post date:** [November 21, 2017, 12:19am UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/5 "2017-11-21T00:19:10Z")

</div>

Adding the database connection name solved the problem.  
Thanks.  
I get the general idea of the three contexts. I’ll study the manual and try more test code, especially with regard to the relationship between gateway tag events and project scripts.

---

<div class="post-metadata">

**Author:** ![Elizabeth\_Myakisheva](https://avatars.discourse-cdn.com/v4/letter/e/9fc348/32.png) [@Elizabeth\_Myakisheva](https://forum.inductiveautomation.com/u/Elizabeth_Myakisheva)\
**Post date:** [June 16, 2023, 2:31pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/6 "2023-06-16T14:31:21Z")

</div>

There's something important missing about this description of contexts: how does a programmer create a Script(jython)/Expression(Ignition)/Database Query that is aware of its context, and how to access some object from a mismatched context when it is necessary?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 16, 2023, 4:48pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/7 "2023-06-16T16:48:44Z")

</div>

> [@Elizabeth\_Myakisheva](#):
>
> that is aware of its context

Do you mean from the designer, or within the java SDK?

> [@Elizabeth\_Myakisheva](#):
>
> access some object from a mismatched context when it is necessary?

You cannot. You must use messages. In part, for some contexts, because the contexts aren't even in the same computer as each other.

---

<div class="post-metadata">

**Author:** ![Elizabeth\_Myakisheva](https://avatars.discourse-cdn.com/v4/letter/e/9fc348/32.png) [@Elizabeth\_Myakisheva](https://forum.inductiveautomation.com/u/Elizabeth_Myakisheva)\
**Post date:** [June 16, 2023, 5:51pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/8 "2023-06-16T17:51:25Z")

</div>

> [@pturmel](#):
>
> Do you mean from the designer, or within the java SDK?

I mean that the Ignition Expression Language can call a Jython script from any of the three contexts using the runScript Expression. And, depending on the context (e.g. Perspective Property update vs Tag Event Scripts vs (... our company doesn't use Vision Clients, so that context only matters in the Designer), many resources (such as the Project Library of scripts) may be unavailable.

This makes calling a script from the project's Project Library when a Gateway-scope tag triggers a Tag Event Script quite difficult, unless I literally just copy-paste the code from the project's Project Library to the Gateway Scripting Project, which introduces the problem of multiple copies of the code that all need to be updated every time I save.

> [@pturmel](#):
>
> You cannot. You must use messages. In part, for some contexts, because the contexts aren't even in the same computer as each other.

I guess that means that Perspective Property Binding expressions can't use a Jython method object or Jython socket object created on the Gateway global shared context even though they are running on the same device?

Is this the right page of the manual to describe messages? [Component Message Handlers - Ignition User Manual 8.1 - Ignition Documentation](https://docs.inductiveautomation.com/display/DOC81/Component+Message+Handlers)

I'm trying to create a locking tag... I forgot what I was doing.

Maybe if I explain the whole problem here it will make sense:  
There's about a dozen programmable controllers connected on the local network, controlling ovens.  
It's OK for a project perspective session or a tag to query a controller and ask it for information (takes about 3 ms), but it's not OK to tell them to load instructions at the same time.

I tried to use a tag to specify which Socket is allowed to load, but when I try to make the Tag Event gray out a button on the Perspective Sessions, I run in to the problem of the script running on the wrong context.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 16, 2023, 8:36pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/9 "2023-06-16T20:36:06Z")

</div>

Sounds like you need to write a driver.

Mainly because you need locking. But jython-based locking in Ignition is extremely difficult to implement correctly, because the jython life cycle for Ignition is based on projects--project saves due to designer edits throw away your code and any locks and sockets you might have created. But if you have threads running with those existing code modules and objects, they'll continue living in parallel until the thread exits.

See this recent topic and all its linked discussions:

> [@Gateway Script Error: super(type, obj): obj must be an instance or subtype of type](https://forum.inductiveautomation.com/t/gateway-script-error-super-type-obj-obj-must-be-an-instance-or-subtype-of-type/51042/9):
>
> Yes. A project save does not kill off any running threads, and does not replace the code within them. The memory of the entire old interpreter, with old objects, is stuck in process memory until the thread finishes. If you are using system.util.getGlobals() and friends, or attaching jython classes to SDK APIs, old and new objects can mix. (And old objects can get stuck.)

TL/DR: Don't use sockets in anything but gateway (not Perspective) scope, and just open/write/read/close in a single operation unless you follow all the "rules" for long-lived threads and objects.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 17, 2023, 12:01am UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/10 "2023-06-17T00:01:27Z")

</div>

> [@Elizabeth\_Myakisheva](#):
>
> when I try to make the Tag Event gray out a button on the Perspective Sessions

I don't really understand what you're trying to do, but picking out this part alone, this is the wrong way to go about this. Tag event scripts should never try to _directly_ manipulate clients; they should instead indirectly manipulate them by for example writing to other tags which the clients bind to, or write to SQL database tables, etc. I.e. affect things that are global. The client should then bind to these things and then do what they need to with that.

---

<div class="post-metadata">

**Author:** ![Jonathan\_Starr](https://avatars.discourse-cdn.com/v4/letter/j/5daacb/32.png) [@Jonathan\_Starr](https://forum.inductiveautomation.com/u/Jonathan_Starr)\
**Post date:** [June 23, 2023, 1:12pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/11 "2023-06-23T13:12:18Z")

</div>

> [@Elizabeth\_Myakisheva](#):
>
> This makes calling a script from the project's Project Library when a Gateway-scope tag triggers a Tag Event Script quite difficult, unless I literally just copy-paste the code from the project's Project Library to the Gateway Scripting Project, which introduces the problem of multiple copies of the code that all need to be updated every time I save.

I have this exact same problem. I am trying to migrate a project from ignition 7.9 to 8.1 and a very simple tag change script, one that is basically a caller that passes an unqualified string from the tag into a project script, doesn't work in 8.1 due to scoping. How do I tell the tag change script where to look now that 'shared' doesn't exist anymore? I think I just need a location reference to hand to the python 'import' function but right clicking the script i need to import doesn't give me a usable location string... I just want to trigger a script on value change how do I do that? I don't want to move all project scripts to gateway events I want all scoping to be global or be given a way to specify the project so I can do normal project like things that work in 7.9. please help.

---

<div class="post-metadata">

**Author:** ![Jonathan\_Starr](https://avatars.discourse-cdn.com/v4/letter/j/5daacb/32.png) [@Jonathan\_Starr](https://forum.inductiveautomation.com/u/Jonathan_Starr)\
**Post date:** [June 23, 2023, 1:19pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/12 "2023-06-23T13:19:28Z")

</div>

> [@pturmel](#):
>
> Gateway project context. Project-specific gateway events and transaction groups exist here. Client tags, windows, and components do not exist. **Tag change scripts** and other events in this context **can use both project. and shared. scripts.**

How, send working example please.

I need to learn how to reference the project from the tag change script, you say it's possible, please advise.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [June 23, 2023, 2:02pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/13 "2023-06-23T14:02:41Z")

</div>

> [@Jonathan\_Starr](#):
>
> I need to learn how to reference the project from the tag change script

You just call them, since the tag change scripts are created within the project they already know what project they are associated to. They will have access to any script libraries that are available within the project, inherited or otherwise.

If you have created a script library called `myFuncs` in your project then you can call the `test()` function inside of that library simply.

```python
myFuncs.test()

```

> [@Jonathan\_Starr](#):
>
> I am trying to migrate a project from ignition 7.9 to 8.1

What was once the Shared scripts is wrapped into a project named 'global' and a script package named 'shared' and that project is set as the Gateway Scripting Project, and any other projects are set to inherit from that project.

If you are doing this migration manually, you may want to consider creating a project to hold any "Global" scripts and then inherit from that project.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 23, 2023, 2:11pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/14 "2023-06-23T14:11:19Z")

</div>

> [@Jonathan\_Starr](#):
>
> I need to learn

I think you are confusing the two **different** kinds of tag listeners.

- Tag `valueChange()` events are defined **on the tag**. These exist in gateway global scope, and can only call scripts that are exposed through the **gateway scripting project**. In v7.9, these would be the scripts under `shared.*`. An upgrade from v7.9 will set up v8+'s more capable hierarchy so these still work.

- Gateway `Tag Change Events` are defined **in a project** , under the scripting section of the designer tree (similar to, but separate from, Vision Client Event scripts). These are configured with a list of tags to monitor, and run a single script for any change to any of those tags. This kind of event script, because it is within a project, has access to the project's script library, and not the scripts offered by the gateway scripting project. (Unless they have overlapping inheritance, which would be true after an upgrade from v7.9)

Consider re-reading the upgrade guide with the above in mind.

---

<div class="post-metadata">

**Author:** ![Jonathan\_Starr](https://avatars.discourse-cdn.com/v4/letter/j/5daacb/32.png) [@Jonathan\_Starr](https://forum.inductiveautomation.com/u/Jonathan_Starr)\
**Post date:** [June 23, 2023, 2:26pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/15 "2023-06-23T14:26:04Z")

</div>

For the next guy

The answer that I needed was almost in this manual section:  
[https://docs.inductiveautomation.com/display/DOC80/Project+Library#ProjectLibrary-GatewayScriptingProject](https://docs.inductiveautomation.com/display/DOC80/Project+Library#ProjectLibrary-GatewayScriptingProject)

What it fails to do is tell you where in gateway settings exactly. So here:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/9/8926ee8f2427eac49ecee0db9cba397db83449f5.png)

This got me past my simple problem. I had embeded the tag change script in a UDT so IDK if the Gateway `Tag Change Events` would have worked but that would probably be cleaner

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 23, 2023, 2:54pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/16 "2023-06-23T14:54:30Z")

</div>

If you are upgrading from v7.9, restoring a v7.9 gateway backup as your starting point would have avoided this grief, as the gateway scripting project would have been set for you, along with the project inheritance to mimic v7.9's behavior.

Also, please point at current documentation. v8.0 has been end-of-life for years and its docs are getting stale.

---

<div class="post-metadata">

**Author:** ![Jonathan\_Starr](https://avatars.discourse-cdn.com/v4/letter/j/5daacb/32.png) [@Jonathan\_Starr](https://forum.inductiveautomation.com/u/Jonathan_Starr)\
**Post date:** [June 23, 2023, 3:25pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/17 "2023-06-23T15:25:29Z")

</div>

> [@pturmel](#):
>
> Also, please point at current documentation. v8.0 has been end-of-life for years and its docs are getting stale.

...

Look I got to that answer after following your link on my actual question:

> [@Call project script from tag change](https://forum.inductiveautomation.com/t/call-project-script-from-tag-change/12086/3):
>
> Hello, I have the same error, and by putting the script in the Client Event Script of a Tag Change variety it start to work perfectly. The thing is that I want the script to run always, even if the client is not open. Calling the script from the Client Event Script would only run the script when the client is open, is that correct?

Why did I come to this thread on tangentially related problem, probably self haltered /sigh.

That 8 and 8.1 are materially different is a very, let's just say, Rockwell-like-move! /rage

Here is the closest link to what people will need in the 8.1 doc's:  
[https://docs.inductiveautomation.com/display/DOC81/Project+Library](https://docs.inductiveautomation.com/display/DOC81/Project+Library)  
scroll to bottom of page get same incomplete instruction from 8.0 doc's and then use the screen shot from my gateway to actually find what you want.

I'm just trying to help the next guy not start a flame war, but I've probably failed at both of those things...

"Computers are a sickness I am the cure." _James Mickens_

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [June 23, 2023, 3:35pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/18 "2023-06-23T15:35:14Z")

</div>

> [@Jonathan\_Starr](#):
>
> I'm just trying to help the next guy not start a flame war, but I've probably failed at both of those things

Heh. We have pretty thick skins around here. (Well, most of us.) Sorry about the old topic link--v8.1 didn't exist in 2019.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 23, 2023, 10:28pm UTC](https://forum.inductiveautomation.com/t/write-to-client-memory-tag-fails-in-tag-event-yet-succeeds-in-client-timer-event/16048/19 "2023-06-23T22:28:32Z")

</div>

Do you mean to say you don't actively update all of the links in your old posts?? 😮
