# system.tag.getConfiguration -\> valid JSON object

**URL:** <https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398>\
**Category:** Ignition\
**Tags:** ignition81, vision\
**Created:** [March 28, 2025, 6:53pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398 "2025-03-28T18:53:44Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [March 28, 2025, 6:53pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/1 "2025-03-28T18:53:44Z")

</div>

I want to export my tag configuration as a valid json object so I can mutate it by script. When I try to run the following, it inevitably bounces off of some custom class objects that come out of the configuration. Is there a "full string" valid JSON mechanism for extracting this information? I can go through the effort of "repairing" the object with some aggressive recursive string casting but if there is a first-party mechanism for this I would prefer it. The script console clearly has some extra decoration to handle these things gracefully but I want to edit the configuration externally.'

```python
conf = system.tag.getConfiguration("[HMI]myProject", True)
myJson = json.dumps(conf) # this inevitably bounces off something like Boolean or TagPath etc.

```

---

<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:** [March 28, 2025, 7:21pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/2 "2025-03-28T19:21:32Z")

</div>

- Deep copy to get pure python/jython dictionaries is required.
- Use `system.util.jsonEncode()`, not python's stdlib.

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [March 28, 2025, 7:24pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/3 "2025-03-28T19:24:09Z")

</div>

Thanks! Thats the kind of thing I was hoping to have exist.

```python
myJson = system.util.jsonEncode(system.tag.getConfiguration("[HMI]", True))
>>> Traceback (most recent call last):
  File "<input>", line 68 in <module>
RuntimeError: maximum recursion depth exceeded (Java StackOverflowError)

```

but uh oh -- it's bricked my script console.

I've tried shrinking the depth on that configuration and it does not work at what I would consider to be an exceptionally reasonably sized configuration.

---

<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:** [March 28, 2025, 7:45pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/4 "2025-03-28T19:45:58Z")

</div>

What about `system.tag.exportTags` instead?

---

<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:** [March 28, 2025, 7:54pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/5 "2025-03-28T19:54:03Z")

</div>

> [@sherman](#):
>
> `maximum recursion depth exceeded`

Oh, I've seen that. Some kind of circular reference.

Try my Integration Toolkit's [system.util.orderedcopy()](https://www.automation-pros.com/toolkit/doc/scripting.html#orderedCopy). It tracks references and copies the loops correctly.

(But `exportTags` is almost certainly better.)

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [March 28, 2025, 8:25pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/6 "2025-03-28T20:25:37Z")

</div>

That sounds like something I'd want! Thanks.

I tried it:

```python
>>> conf = system.tag.getConfiguration("[HMI]", True) 
>>> system.tag.exportTags(None, conf, True)
Java Traceback:
Traceback (most recent call last):
  File "<input>", line 68, in <module>
	at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.exportTags(AbstractTagUtilities.java:571)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.base/java.lang.reflect.Method.invoke(Unknown Source)

java.lang.ClassCastException: java.lang.ClassCastException: class com.inductiveautomation.ignition.common.config.PyTagDictionary cannot be cast to class java.lang.String (com.inductiveautomation.ignition.common.config.PyTagDictionary is in unnamed module of loader java.net.URLClassLoader @1adaa42b; java.lang.String is in module java.base of loader 'bootstrap')

	at org.python.core.Py.JavaError(Py.java:545)

	at org.python.core.Py.JavaError(Py.java:536)

	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:192)

	at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction. __call__ (ScriptManager.java:553)

	at org.python.core.PyObject. __call__ (PyObject.java:494)

	at org.python.core.PyObject. __call__ (PyObject.java:498)

	at org.python.pycode._pyx405.f$0(<input>:68)

	at org.python.pycode._pyx405.call_function(<input>)

	at org.python.core.PyTableCode.call(PyTableCode.java:173)

	at org.python.core.PyCode.call(PyCode.java:18)

	at org.python.core.Py.runCode(Py.java:1703)

	at org.python.core.Py.exec(Py.java:1747)

	at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:277)

	at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:130)

	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:628)

	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:616)

	at java.desktop/javax.swing.SwingWorker$1.call(Unknown Source)

	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

	at java.desktop/javax.swing.SwingWorker.run(Unknown Source)

	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

	at java.base/java.lang.Thread.run(Unknown Source)

Caused by: java.lang.ClassCastException: class com.inductiveautomation.ignition.common.config.PyTagDictionary cannot be cast to class java.lang.String (com.inductiveautomation.ignition.common.config.PyTagDictionary is in unnamed module of loader java.net.URLClassLoader @1adaa42b; java.lang.String is in module java.base of loader 'bootstrap')

	at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.exportTags(AbstractTagUtilities.java:571)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.base/java.lang.reflect.Method.invoke(Unknown Source)

	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:190)

	... 19 more

Traceback (most recent call last):
  File "<input>", line 68, in <module>
	at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.exportTags(AbstractTagUtilities.java:571)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.base/java.lang.reflect.Method.invoke(Unknown Source)

java.lang.ClassCastException: java.lang.ClassCastException: class com.inductiveautomation.ignition.common.config.PyTagDictionary cannot be cast to class java.lang.String (com.inductiveautomation.ignition.common.config.PyTagDictionary is in unnamed module of loader java.net.URLClassLoader @1adaa42b; java.lang.String is in module java.base of loader 'bootstrap')
>>> 

```

---

<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:** [March 28, 2025, 8:29pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/7 "2025-03-28T20:29:34Z")

</div>

> [@sherman](#):
>
> ```python
> >>> conf = system.tag.getConfiguration("[HMI]", True) 
> >>> system.tag.exportTags(None, conf, True)
> 
> ```

> **[system.tag.exportTags | Ignition User Manual](https://docs.inductiveautomation.com/docs/8.1/appendix/scripting-functions/system-tag/system-tag-exportTags)**
>
> Exports tags to a file on a local file system.

second argument is not whatever you get from `getConfiguration`...

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [March 28, 2025, 8:39pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/8 "2025-03-28T20:39:52Z")

</div>

> [@sherman](#):
>
> ```python
> at java.base/java.lang.reflect.Method.invoke(Unknown Source)
> 
> ```

Ah that's true, it needs to be a list of paths. Lets try again!

```python
myJson = system.tag.exportTags(None, ["[HMI]"], True)

```

It works! At least it returns an object that I can write to a file myself; trying to write directly takes my linux path (running containerized) and seems to have flipped it to a `C:\{my path with / -> \}` path without my consent. i.e.

```python
>>> print(system.tag.exportTags("/myFileSystem/tags.json", ["[HMI]"], True)) 
C:\myFileSystem\tags.json

```

I'm guessing that method hasn't been updated to support containerized/linux environments?

(Addional QOL: please consider adjusting all of the scripting functions that take lists of things to auto-list a single non-list argument) `if not isinstance(arg, list): arg = list(arg)`)

---

<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:** [March 28, 2025, 8:44pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/9 "2025-03-28T20:44:12Z")

</div>

You're running this in the Designer Script console, so I'm not sure your containerized environment is relevant. You're on Windows, so you get a Windows path. It wrote to a file on the host running the Designer.

---

<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:** [March 28, 2025, 8:47pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/10 "2025-03-28T20:47:21Z")

</div>

Also this seems to be poorly documented and only inferred from an example, but if you omit the `filePath` parameter it'll just return the export contents:

```python
# Exports the entire tag provider named "default" as a string, and
# returns the string to a "tags" variable.
tags = system.tag.exportTags(tagPaths = ["[default]"])

```

---

<div class="post-metadata">

**Author:** ![sherman](https://avatars.discourse-cdn.com/v4/letter/s/e5b9ba/32.png) [@sherman](https://forum.inductiveautomation.com/u/sherman)\
**Post date:** [March 28, 2025, 9:24pm UTC](https://forum.inductiveautomation.com/t/system-tag-getconfiguration-valid-json-object/104398/11 "2025-03-28T21:24:06Z")

</div>

Ah yes my old Achilles heel. My gateway message helpers that I use to write files managed to have me forget about this for awhile. I used the non-pathed option to get the data and write it to my real filesystem using that, but spaced on the direct write.
