# Passing a list into runScript() expression binding

**URL:** <https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [May 10, 2025, 2:07pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125 "2025-05-10T14:07:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [May 10, 2025, 2:07pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/1 "2025-05-10T14:07:23Z")

</div>

Here's my test script.

```python
def addStar(arr):
	return [x + "***" for x in arr]

```

Running `myScripts.addStar(['brush', 'comb'])` in Script Console gives me  
`['brush ***', 'comb***']`. All good so far.

I know that one can't create lists directly in expressions (see [Indirect Tag History Binding Expression - #3 by PGriffith](https://forum.inductiveautomation.com/t/indirect-tag-history-binding-expression/86836/3)) so I've created a custom property `myArr` to hold the list `['brush', 'comb']`.

On another tag I've created an expression binding:  
`runScript("myScripts.addStar", 0, {view.custom.myArr})`

The Binding Preview gives the error message,

> Error\_ExpressionEval("Error executing script for runScript) expression:myscripts.addStar")

Can anyone give me some guidance on this?

---

<div class="post-metadata">

**Author:** ![hunterdg](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/hunterdg/32/67774_2.png) [@hunterdg](https://forum.inductiveautomation.com/u/hunterdg)\
**Post date:** [May 10, 2025, 2:56pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/2 "2025-05-10T14:56:20Z")

</div>

Make a simple script to return the type of the passed parameter (it won’t be list).

Then modify your addStar script to handle the actual type

Objects are Java hashmaps, lists are Java arrays if I recall correctly.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [May 10, 2025, 3:08pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/3 "2025-05-10T15:08:43Z")

</div>

Thanks for the tip.

```python
def addStar(arr):
	return type(arr)

```

Script console `myScripts.addStar(['gh', 'fd'])` returns `<type 'list'> ` as expected.

The expression binding `runScript("myScripts.addStar", 0, {view.custom.myArr})` now returns `class.org.python.core.PyArray`.

How do I convert that to a list / array?

---

<div class="post-metadata">

**Author:** ![hunterdg](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/hunterdg/32/67774_2.png) [@hunterdg](https://forum.inductiveautomation.com/u/hunterdg)\
**Post date:** [May 10, 2025, 3:56pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/4 "2025-05-10T15:56:33Z")

</div>

JSON or GSON encode/decode.

Don’t have my snippets with me but may report back shortly with example

---

<div class="post-metadata">

**Author:** ![hunterdg](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/hunterdg/32/67774_2.png) [@hunterdg](https://forum.inductiveautomation.com/u/hunterdg)\
**Post date:** [May 10, 2025, 4:01pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/5 "2025-05-10T16:01:36Z")

</div>

Type hints are wrong (this is an old version in my clipboard history) but code usually works. Sometimes GSON can’t handle nested types. I think Phil’s module has a method to do this as well, but assume you’re not using it in this case

```python
	@staticmethod
	def unWrap(wrappedObj): # type: (WrappedObject | Sequence[WrappedObject]) -> UnwrappedObject | Sequence[UnwrappedObject]
		"""Unwraps Objects to dict - Used for finnicky JSON encoding and message handlers
			Example: `_system.util.unWrap(self.view.params)`

		Args:
			wrappedObj: WrappedObject | Sequence[WrappedObject]

		Returns:
			dict: UnwrappedObject | Sequence[UnwrappedObject]
		"""		
		# return dict(wrappedObj) # shallow dict, sendRequest doesn't like
		# return system.util.jsonDecode(system.util.jsonEncode(wrappedObj)) # chokes (weird types/depth limitations)
		# import json
		# return json.loads(json.dumps(wrappedObj)) # # chokes (weird types/depth limitations)
		# https://forum.inductiveautomation.com/t/function-to-convert-json-string-or-python-dict-into-objectwrapper/32861/15
		from com.inductiveautomation.ignition.common import TypeUtilities
		return TypeUtilities.gsonToPy(TypeUtilities.pyToGson(wrappedObj))

```

Related: [Curiosity: why are documented methods throwing AttributeError (is my ignorance showing?) - #14 by hunterdg](https://forum.inductiveautomation.com/t/curiosity-why-are-documented-methods-throwing-attributeerror-is-my-ignorance-showing/85081/14)

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [May 10, 2025, 4:11pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/6 "2025-05-10T16:11:48Z")

</div>

Thanks for all that effort. It all seems a bit bonkers. I'm passing a list. What happened to it on the way to the script. (And all of this is because I'm being a good boy and moving code out of expression transform scripts and into the project library.)

I had a quick go of your function (which now introduces the notion of GSON!) but couldn't clear the error.

I'm going to fix a lawnmower instead. I hope there aren't left-hand threads holding the blade on.

---

<div class="post-metadata">

**Author:** ![hunterdg](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/hunterdg/32/67774_2.png) [@hunterdg](https://forum.inductiveautomation.com/u/hunterdg)\
**Post date:** [May 10, 2025, 4:13pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/7 "2025-05-10T16:13:41Z")

</div>

`list(param)` might work for your simple use case.

Perspective parameters are not python objects, they’re Java objects.

Bet you could do a parameter binding chained with a python transform that just calls the library script and passes in `{value}`. That might handle type conversion transparently.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [May 10, 2025, 4:25pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/8 "2025-05-10T16:25:02Z")

</div>

`return type(list(arr))` gives me `class.org.python.core.PyList` on the Expression Preview.

`return list(arr)` gives me `["brush", "comb"]` as does `return arr`.

`return [x + "***" for x in list(arr)]` gives me the error again.

Thanks for sticking with me on this.

---

<div class="post-metadata">

**Author:** ![hunterdg](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/hunterdg/32/67774_2.png) [@hunterdg](https://forum.inductiveautomation.com/u/hunterdg)\
**Post date:** [May 10, 2025, 4:52pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/9 "2025-05-10T16:52:55Z")

</div>

PyList is what you want so you’re making progress.

Maybe that wasn’t the problem in the first place

I bet `return type(x[0])` is a QualifiedValue

Try `return [x.value + "***" for x in list(arr)]`

You can modify that test script with a try/except error as e; return e to see the actual error as you refine.

(Phil’s module also has an `unQualify()` function for precisely this purpose lol)

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [May 10, 2025, 4:56pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/10 "2025-05-10T16:56:53Z")

</div>

> [@hunterdg](#):
>
> I bet `return type(x[0])` is a QualifiedValue

Bingo!  
`return [x.value + "***" for x in list(arr)]` returns `["brush***", "comb***"]`.  
So that was it. Thank you very much.

Meanwhile the lawnmower deck is cast aluminium and one of the engine mounting locations has cracked off. It might be repairable - but maybe not on this forum.

---

<div class="post-metadata">

**Author:** ![hunterdg](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/hunterdg/32/67774_2.png) [@hunterdg](https://forum.inductiveautomation.com/u/hunterdg)\
**Post date:** [May 10, 2025, 4:57pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/11 "2025-05-10T16:57:26Z")

</div>

😆

Might not need list() anymore.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [May 10, 2025, 5:00pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/12 "2025-05-10T17:00:37Z")

</div>

Correct. `return [x.value + "***" for x in arr]` does the job. Better again.

---

<div class="post-metadata">

**Author:** ![hunterdg](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/hunterdg/32/67774_2.png) [@hunterdg](https://forum.inductiveautomation.com/u/hunterdg)\
**Post date:** [May 10, 2025, 5:19pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/13 "2025-05-10T17:19:48Z")

</div>

My bad for overcomplicating right off the bat 🤦‍♂️

Cheers

---

<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:** [May 11, 2025, 1:21am UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/15 "2025-05-11T01:21:39Z")

</div>

_Psssst!_

[unQualify()](https://www.automation-pros.com/toolkit/doc/scripting.html#unqualify)

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [May 11, 2025, 7:54am UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/16 "2025-05-11T07:54:20Z")

</div>

I'm aware of that function but your Integration Toolkit isn't installed on the customer's gateway. I'll be surprised if they'll add it.

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [May 11, 2025, 8:53am UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/17 "2025-05-11T08:53:35Z")

</div>

What if you changed your function to take an arbitrary number of values instead of a list ?

```python
def add_stars(*args):
	return [arg + "***" for arg in args]

```

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

I don't know where your values come from, so this may not be practical for your use case, but if it is it will remove the need for a temporary list in your custom properties.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [May 11, 2025, 9:05am UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/18 "2025-05-11T09:05:37Z")

</div>

Thanks, Pascal. I was aware of that option from the docs. In my case I'd be splitting up an array from the custom prop which would make the expression more complex. Passing the Java object into the script and sorting it out there suits me better.

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [May 11, 2025, 9:32am UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/19 "2025-05-11T09:32:23Z")

</div>

My point was that you might skip that custom prop array entirely, depending on how exactly you populate that array.

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [May 12, 2025, 1:51pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/20 "2025-05-12T13:51:13Z")

</div>

I created a couple library functions for this scenario to convert lists and dictionaries of Qualified Values:

```python
def getListOfValues(listOfQV):
	if listOfQV is None:
		return None
	return [val.value for val in listOfQV]
	
def getDictOfValues(dictOfQV):
	if dictOfQV is None:
		return None
	out = {}
	for key in dictOfQV.keys():
		out[key] = dictOfQV[key].value
	return out

```

---

<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:** [May 12, 2025, 1:57pm UTC](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125/21 "2025-05-12T13:57:03Z")

</div>

> [@Ryan\_Deardorff](#):
>
> ```python
> out = {}
> for key in dictOfQV.keys():
> out[key] = dictOfQV[key].value
> return out
> 
> ```

Consider instead:

```python
	return dict([(k, qv.value) for (k, qv) in dictOfQV.items()])

```

[Next page](https://forum.inductiveautomation.com/t/passing-a-list-into-runscript-expression-binding/106125.md?page=2)
