The predefined category keys are defined as constants in WellKnownTagProps as CAT_*. Only those will get an icon in the tag editor tree. Additional strings are defined in bundles by 3rd party modules, and my toolkit supplies a couple. Any other keys used for tag prop categories display with question marks.
Raw localized strings (key-less) crash the tag editor. Blank tree, blank list of props, no error thrown. ![]()
Raw localized strings are fine for display name and description. (And the only practical way to provide those outside of a 3rd party module.)
Wacky ![]()
Automation Professionals is pleased to announce new Production releases of this module, with bug fixes to address anomalies in the designer tag browser, discussed over here:
For Ignition v8.3.x: v2.1.6.262181311
For Ignition v8.1.x: v2.1.6.262171502
The tag browser issues do not appear to be other than cosmetic, so upgrading is not urgent.
Edit: v8.3 replaced with minor fix to @runInGateway permissions.
I'm running into something similar to this on a 8.3.8 Gateway and version 2.1.6 of Integration Toolkit. The difference I'm getting is that the expression using this function is giving me an error and not returning a value. The error is citing the pageVarMap function specifically.
The module is marked as running with no errors, and I did not see any errors in the log related to the toolkit.
I did find the following stack trace in the logs as an INFO level message, but since this appears to be firing off on some tags in our tag tree I'm not sure its related to the expression error in the perspective view.
Stack Trace
java.lang.LinkageError: loader com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader @59680116 attempted duplicate class definition for com.automation_pros.simaids.gateway.expressions.SessionVarMap. (com.automation_pros.simaids.gateway.expressions.SessionVarMap is in unnamed module of loader com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader @59680116, parent loader com.inductiveautomation.ignition.gateway.modules.NativeLibraryManagerImpl @bc48999)
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(Unknown Source)
at java.base/java.security.SecureClassLoader.defineClass(Unknown Source)
at java.base/java.net.URLClassLoader.defineClass(Unknown Source)
at java.base/java.net.URLClassLoader$1.run(Unknown Source)
at java.base/java.net.URLClassLoader$1.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at java.base/java.net.URLClassLoader.findClass(Unknown Source)
at com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:35)
at com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader.loadClass(ModuleClassLoader.java:102)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
at com.automation_pros.simaids.gateway.GatewayHook.configureFunctionFactory(GatewayHook.java:102)
at com.inductiveautomation.ignition.gateway.IgnitionGateway.configureFunctionFactory(IgnitionGateway.java:3100)
at com.inductiveautomation.ignition.gateway.IgnitionGateway.getExpressionFunctionFactory(IgnitionGateway.java:3088)
at com.inductiveautomation.ignition.gateway.tags.TagProviderImpl.getExpressionFunctionFactory(TagProviderImpl.java:1299)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.ExecutableTag.getExpressionParseContext(ExecutableTag.java:966)
at com.inductiveautomation.ignition.gateway.tags.actors.factories.alarming.AlarmingActor.ensureEvaluatorCreated(AlarmingActor.java:299)
at com.inductiveautomation.ignition.gateway.tags.actors.factories.alarming.AlarmingActor.initialize(AlarmingActor.java:89)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.ExecutableTag.manageActor(ExecutableTag.java:268)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.ExecutableTag.configureActors(ExecutableTag.java:844)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.ExecutableTag.applyPropertyChangesToTag(ExecutableTag.java:655)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.managePropertyChanges(BasicTagDefinition.java:874)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.startPropModel(BasicTagDefinition.java:513)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.activate(BasicTagDefinition.java:1067)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.complex.InheritedExecutableTag.activate(InheritedExecutableTag.java:30)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.startupInternal(BasicTagDefinition.java:1051)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.startup(BasicTagDefinition.java:1034)
at java.base/java.util.ArrayList.forEach(Unknown Source)
at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.FolderNode.startup(FolderNode.java:443)
at com.inductiveautomation.ignition.gateway.tags.runtime.ProviderRootNodeImpl.loadConfiguration(ProviderRootNodeImpl.java:364)
at com.inductiveautomation.ignition.gateway.tags.TagProviderImpl$TagStorageListener.onInitialLoad(TagProviderImpl.java:1534)
at com.inductiveautomation.ignition.gateway.tags.config.storage.resource.TagConfigLoader$ProcessUDTAction.compute(TagConfigLoader.kt:248)
at com.inductiveautomation.ignition.gateway.tags.config.storage.resource.TagConfigLoader$ProcessUDTAction.compute(TagConfigLoader.kt:236)
at java.base/java.util.concurrent.RecursiveTask.exec(Unknown Source)
at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
at java.base/java.util.concurrent.ForkJoinTask.invokeAll(Unknown Source)
at com.inductiveautomation.ignition.gateway.tags.config.storage.resource.TagConfigLoader$ProcessUDTAction.compute(TagConfigLoader.kt:255)
at com.inductiveautomation.ignition.gateway.tags.config.storage.resource.TagConfigLoader$ProcessUDTAction.compute(TagConfigLoader.kt:236)
at java.base/java.util.concurrent.RecursiveTask.exec(Unknown Source)
at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
Haven't been able to reproduce with v8.3.8 yet. Unknown function suggests a problem registering at module startup. Can you send a wrapper log from gateway startup through RUNNING? (To my support email, please.)
File has been sent your way, hopefully you can gleam something from it.
Yeah, lots of these:
INFO | jvm 2 | 2026/08/26 13:55:12 | I [c.a.s.g.GatewayHook ] [13:55:12.484]: Skipped loading Perspective-specific expression functions tag=Tag_Path_3
INFO | jvm 2 | 2026/08/26 13:55:12 | java.lang.LinkageError: loader com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader @4c0cabce attempted duplicate class definition for com.automation_pros.simaids.gateway.expressions.SessionVarMap. (com.automation_pros.simaids.gateway.expressions.SessionVarMap is in unnamed module of loader com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader @4c0cabce, parent loader com.inductiveautomation.ignition.gateway.modules.NativeLibraryManagerImpl @bc48999)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.lang.ClassLoader.defineClass1(Native Method)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.lang.ClassLoader.defineClass(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.security.SecureClassLoader.defineClass(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.net.URLClassLoader.defineClass(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.net.URLClassLoader$1.run(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.net.URLClassLoader$1.run(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.security.AccessController.doPrivileged(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.net.URLClassLoader.findClass(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:35)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.modules.ModuleClassLoader.loadClass(ModuleClassLoader.java:102)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.automation_pros.simaids.gateway.GatewayHook.configureFunctionFactory(GatewayHook.java:102)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.IgnitionGateway.configureFunctionFactory(IgnitionGateway.java:3100)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.IgnitionGateway.getExpressionFunctionFactory(IgnitionGateway.java:3088)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.TagProviderImpl.getExpressionFunctionFactory(TagProviderImpl.java:1299)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.ExecutableTag.getExpressionParseContext(ExecutableTag.java:966)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.actors.factories.alarming.AlarmingActor.ensureEvaluatorCreated(AlarmingActor.java:299)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.actors.factories.alarming.AlarmingActor.initialize(AlarmingActor.java:89)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.ExecutableTag.manageActor(ExecutableTag.java:268)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.ExecutableTag.configureActors(ExecutableTag.java:844)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.ExecutableTag.applyPropertyChangesToTag(ExecutableTag.java:655)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.managePropertyChanges(BasicTagDefinition.java:874)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.startPropModel(BasicTagDefinition.java:513)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.activate(BasicTagDefinition.java:1067)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.complex.InheritedExecutableTag.activate(InheritedExecutableTag.java:30)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.startupInternal(BasicTagDefinition.java:1051)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.BasicTagDefinition.startup(BasicTagDefinition.java:1034)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.ArrayList.forEach(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.nodes.FolderNode.startup(FolderNode.java:443)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.runtime.ProviderRootNodeImpl.loadConfiguration(ProviderRootNodeImpl.java:364)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.TagProviderImpl$TagStorageListener.onInitialLoad(TagProviderImpl.java:1534)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.config.storage.resource.TagConfigLoader$ProcessUDTAction.compute(TagConfigLoader.kt:248)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.config.storage.resource.TagConfigLoader$ProcessUDTAction.compute(TagConfigLoader.kt:236)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.concurrent.RecursiveTask.exec(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.concurrent.ForkJoinTask.invokeAll(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.config.storage.resource.TagConfigLoader$ProcessUDTAction.compute(TagConfigLoader.kt:255)
INFO | jvm 2 | 2026/08/26 13:55:12 | at com.inductiveautomation.ignition.gateway.tags.config.storage.resource.TagConfigLoader$ProcessUDTAction.compute(TagConfigLoader.kt:236)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.concurrent.RecursiveTask.exec(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
INFO | jvm 2 | 2026/08/26 13:55:12 | at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
BEFORE this:
INFO | jvm 2 | 2026/08/26 13:55:21 | I [ModuleInstance ] [13:55:21.563]: Starting up module 'com.automation_pros.simaids' v2.1.6 (b262181311)... module-name=Integration Toolkit
However, I don't understand why anyone would expect it to work in an expression tag. It is only documented to work in Perspective expression bindings--it needs access to Perspective's thread locals.
That's the strange part, those tags were not built / configured to use any of the expression functions from your module. I just installed the module today to use your spreadsheet import tool.
Hmmm. My toolkit declares a dependency on Perspective, to make it possible to reference its classes for the thread locals. I need to experiment some more.
I'll make it more fun, all the tags listed in the log that I've found are OPC or Memory tags, unless someone made one instance an expression tag somewhere that I missed and that's what is tripping up the module. If I had the full tag path in the log that would make it easier to nail down which one exactly it is.
I looked at the raw JSON of each tag in the log that I could find to make sure there wasn't a leftover expression from someone changing the type of tag.
So, I installed this module to try to take advantage of the Tag Actors functionality to republish some value from one device to another. What I noticed though is that there's an opcServer parameter that gets added to every tag which seems to possibly conflict with my own 'OPCServer' parameter that we have on all our OPC tags. What is this used for? I've got this value configured on all my tags and while right now the value hasn't been changed, I worry that it may get set by some configuration of the tag actors functionality if I'm ever using a different OPC server for the republish than I am for my tag.
I also didn't see anything in the documentation about it, so was curious if this written to by the module or what the risk is in using the module and conflicting with all of our tags existing parameters.
My module uses the opcServer prop definition to obtain its acceptable value list for use with the destination OPC Server fields that the tag actors need. Should not change its appearance for other uses.
So it's it ok for me to write to it, or is there a chance it will get overwritten by the module?
My module doesn't write to any tag props.
