# Shared script works on button, not on alarm pipeline

**URL:** <https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806>\
**Category:** Ignition\
**Tags:** ignition81, perspective\
**Created:** [July 24, 2023, 6:34pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806 "2023-07-24T18:34:32Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 24, 2023, 6:34pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/1 "2023-07-24T18:34:33Z")

</div>

i have a script in the project library. i call it from a button and it works. i call it from an alarm pipeline and it doesn't.

`userFunctions.multiUserFunctions.getUserEmails('SomeUserSource')`  
 ![Screenshot 2023-07-24 123404](https://us1.discourse-cdn.com/inductiveautomation/original/3X/1/6/1600db600fcd9351a1b7beddb99ef64bcf234743.png)

the odd thing is, if i paste the _actual script_ into the alarm, it works just fine. confusion abounds. 😕

the manual is a little fuzzy, since it's from several versions ago, but [this post suggested new information](https://forum.inductiveautomation.com/t/question-how-to-use-project-scripts/23354/3). it doesn't elaborate on where to put _shared_ scripts, but at least a modification of calling _project_ scripts.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 24, 2023, 6:42pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/2 "2023-07-24T18:42:11Z")

</div>

`userFunctions` or `user_functions`?

---

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 24, 2023, 6:42pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/3 "2023-07-24T18:42:56Z")

</div>

old screenshot. `userFunctions`😛 my militant efforts to standardize naming conventions: everybody here hates the underscore... fine. but be **consistent**.

EDIT: i read further and found that Gateway Scripts are found in the defined `Gateway Script Project` on the `Config` page under `Gateway Settings`. so that's one niggly bit sorted. \*phew\*.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 24, 2023, 7:00pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/4 "2023-07-24T19:00:55Z")

</div>

> [@ian.sebryk](#):
>
> EDIT: i read further and found that Gateway Scripts are found in the defined `Gateway Script Project` on the `Config` page under `Gateway Settings`. so that's one niggly bit sorted. _phew_.

For what it's worth, I think this is just a bug.

The 'Gateway Scripting Project' setting _should_ only be relevant for truly globally scoped stuff (namely, tags). Since you define alarm pipelines in a project (now, you didn't in older versions) they should 'know' about the local project's scripting environment. I want to say there's a ticket for this, but I can't find it - if indeed it's even the case.

---

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 24, 2023, 7:21pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/5 "2023-07-24T19:21:06Z")

</div>

> [@paul-griffith](#):
>
> _should_ only be relevant for truly globally scoped stuff

would this not include functions we call and use on literally **every** project? i am wondering if, now that i actually have this global script project defined, if that possible bug can be sidestepped by calling directly from the Ignition Gateway...? i'll give it a go and report.

and, for completion sake, i'm assuming that there's nothing wrong with my syntax: it _should_ work. it just doesn't. correct? and, moving forward with the centralized script repo concept, the call would now be:  
`shared.userFunctions.multiUserFunctions.getUsersEmails('SomeUserSource')`, correct? (and, yes, i caught my previous typo 😃 )

---

<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:** [July 24, 2023, 7:26pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/6 "2023-07-24T19:26:58Z")

</div>

In what way does this script "not work"? What is the error?

---

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 24, 2023, 7:30pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/7 "2023-07-24T19:30:18Z")

</div>

AFAIK, no error. nothing.

- raw script on alarm pipeline: generates email.
- project script call on button: generates email.
- project script call from alarm pipeline: ........\*_crickets\*_........

as @paul-griffith mentioned above, this _may_ be a bug and i'm going to try and sidestep it with a global script call and see if that works. it's where i am trying to migrate anyway...

---

<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:** [July 24, 2023, 7:30pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/8 "2023-07-24T19:30:31Z")

</div>

Look in the gateway logs.

---

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 24, 2023, 7:32pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/9 "2023-07-24T19:32:13Z")

</div>

\*_sigh\*_ that's Wednesday to-do item. 😛 there is no logging system in place here... yet.

\*_scribbles on calendar\*_ okay... fine. i'll do it tomorrow...

---

<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:** [July 24, 2023, 7:32pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/10 "2023-07-24T19:32:45Z")

</div>

No, Ignition's gateway logs. Go to the Status \> Logs section of the Ignition Gateway.

---

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 24, 2023, 7:35pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/11 "2023-07-24T19:35:12Z")

</div>

oh... you mean the `Streaming Text Jungle of Doom`? 😭 why do you hate me so?? 😃 😃 😃

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 24, 2023, 9:42pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/12 "2023-07-24T21:42:32Z")

</div>

No, the gateway webpage that's nicely sortable and filterable.

> [@ian.sebryk](#):
>
> would this not include functions we call and use on literally **every** project? i am wondering if, now that i actually have this global script project defined, if that possible bug can be sidestepped by calling directly from the Ignition Gateway...? i'll give it a go and report.

That's not what I described nor what the setting does.

The 'Gateway Scripting Project' _setting_ does one thing and one thing only:  
It tells scripts that are executing _outside_ of any project scope where they can look for a shared script library. Note the term project script **library**. There's no automatic translation of a call from client/designer scope to gateway scope, or vice versa. We're not serving up magic, even if it seems like it sometimes.  
So when you are in a script that's going to be executed by the gateway (tag event scripts, gateway event scripts, Perspective scripts, alarm pipelines, reports), it will have _some_ contextual automatic import(s), where some can be 1. the project it belongs to, if it's a resource you authored along with your project, 2. the 'gateway scripting project', if it's something that doesn't belong to a project, such as a tag, or 3. **nothing** , if it's a global resource like a tag and the gateway scripting project is not set.

> [@ian.sebryk](#):
>
> i'm assuming that there's nothing wrong with my syntax: it _should_ work. it just doesn't. correct?

Well, I don't know, because you haven't posted your code 🙂 But conceptually I agree with your basic premise that the same text that works directly in the pipeline should work if invoked as a call to the project library.

> [@ian.sebryk](#):
>
> the call would now be:  
> `shared.userFunctions.multiUserFunctions.getUsersEmails('SomeUserSource')`

No. You don't need any `shared` prefix \_unless your actual project script library path includes `shared`. Back in older versions of Ignition, where there was a special one-off "global" project, there were two special namespaces: `project` and `shared`. As of Ignition 8.0.0, there are no 'special' namespaces - whatever names you put into the top-level of the project library are effectively automatically imported (according to the project/no project scope described above).

As a general note: Please try not to rush to pattern-match things we're describing to concepts you may be more familiar with from other systems. I promise Kevin, Phil, myself, and anyone else who's offering you advice is not trying to use confusing terminology - we're just using "standard parlance" around Ignition, which is unfortunately overloaded because English only has so many ways to describe the same things and every possible stack is just that little bit different.

---

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 25, 2023, 2:47pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/13 "2023-07-25T14:47:27Z")

</div>

> [@paul-griffith](#):
>
> we're just using "standard parlance" around Ignition, which is unfortunately overloaded because English only has so many ways to describe the same things and every possible stack is just that little bit different.

oh, for sure! i speak 5 languages and am fluent in 'this-kinda-means-that-but-more-this'. 🙂 i am VERY grateful for the patience you have with my questions. i know i'm a bit of an oddball, but i very much want to understand this new ecosystem.

to that end, in a nutshell, i am tasked with refactoring the spaghetti that is our current codebase for our client projects. they are all roughly similar and are doing roughly the same things. which begs for some standardization. i'm wanting to build a common repo of scripts for the more common tasks so guys aren't writing variations and interpretations of the same thing to get fundamental data like permissions, contact info, and a host of other common tasks. the problem we have is that, currently, because of the spaghetti monster of our predecessor, there's no structure to what is currently running. so i get to _learn_ Ignition **while** refactoring and trying to follow the stream of consciousness that built this stuff. and coming from a strong background of development, i have old habits that need refactoring themselves.

1. so what i'm looking to do: build a common toolset of basic functions accessible by ALL projects
2. what i'm looking for: the ability to _see_ the contents of what the _current_ codebase is generating. i think i have that licked.

does the Gateway Script Project let me do #1? i'm still wobbly on Gateway execution vs Project execution. if i read you correctly, if i call a function the does not reside in the project scripts, it will then look for them in the Gateway Script Project. is that correct?

---

<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:** [July 25, 2023, 3:06pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/14 "2023-07-25T15:06:39Z")

</div>

> [@ian.sebryk](#):
>
> if i call a function the does not reside in the project scripts, it will then look for them in the Gateway Script Project

Sorry, no.

Projects have an inheritance structure, and scripts in one project can use the scripts in their parent (or parents) project(s). (No, not not multiple inheritance, sadly. Just linear up the chain of parents.)

Objects that live **outside** of any projects, like tags, merely pretend to belong to the gateway scripting project, for scripting purposes.

Since you've be posting things that include the `shared.*` and `project.*` scripting namespaces, it might help you to know that those are holdovers from Ignition v7.9 and before. In those older versions, there was no inheritance, except that `shared.*` scripts were visible throughout the system. The upgrade process to v8+ would create an inheritble `global` project with the `shared.*` scripts, then regular leaf projects inheriting from that, and with the global scripting project preset to `global`. This would mimic the v7.9 behavior in v8+. You are not bound to continue doing so, and probably should not.

I recommend you create:

- A global, inheritable project that carries the old `shared.*` namespace and it successors. Place well-tested common functions and classes here.

- An inheritable project, inheriting from the global project, that carries all well-tested common scripting functions and classes you need for your user interfaces. Include well-tested common user interface elements such as Vision templates, Vision popup windows, and Perspective views that might be considered template-equivalents. Perhaps separate global projects for Vision versus Perspective, if applicable.

- Leaf projects as needed for user interfaces, inheriting from the above global UI project. New windows, templates, views, and scripting functions should live in a leaf project until they are sufficiently well-tested to be relied upon in an inheritable project.

- An inheritable project inheriting from global that carries all well-tested common scripting functions useful in non-UI gateway background tasks, and all all script functions needed by tag events. Make this your gateway scripting project.

- Leaf projects as needed (inheriting from the global background or global project) for gateway background tasks that are not tag events, and not intimately tied to a user interface project.

---

<div class="post-metadata">

**Author:** ![Felipe\_CRM](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@Felipe\_CRM](https://forum.inductiveautomation.com/u/Felipe_CRM)\
**Post date:** [July 25, 2023, 3:11pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/15 "2023-07-25T15:11:06Z")

</div>

> [@ian.sebryk](#):
>
> common toolset of basic functions accessible by ALL projects

I think it's possible to achieve something like this through inheritable projects, but resource inheritance is a whole can of worms, with rules on what is ok to inherit and what will give you heartburn if you try to inherit.

Maybe you can write a module 😁 joking, mostly

Edit: Phil beat me to the punch while I was writing this. I'll just add that whatever you do, don't try to inherit _event_ scripts like tag change scripts

---

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 25, 2023, 3:57pm UTC](https://forum.inductiveautomation.com/t/shared-script-works-on-button-not-on-alarm-pipeline/76806/16 "2023-07-25T15:57:07Z")

</div>

this is a lot to digest and i'm going to need a bit to chew through this as i don't fully understand inherited projects yet. 🤯 i need a new mental model entirely. i'm going to go, take what i have here, and tinker to try and comprehend better... 🤔

thanks all.
