# Attribute Error in Component Custom Method

**URL:** <https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712>\
**Category:** Ignition\
**Tags:** ignition81, scripting, vision\
**Created:** [June 11, 2021, 6:08pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712 "2021-06-11T18:08:04Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![edward.fowler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/edward.fowler/32/24179_2.png) [@edward.fowler](https://forum.inductiveautomation.com/u/edward.fowler)\
**Post date:** [June 11, 2021, 6:08pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/1 "2021-06-11T18:08:04Z")

</div>

The script (below) when residing in a Project Library works when I call it from a button script. To implement best practices I put placed the script as a custom method in my button component.

```auto
def incrementVerNum4th(self, projectArea, topic, notes):
	newVerNum = system.tag.readBlocking('[gw1]_Project Version Information/verNum4th')[0].value + 1
	system.tag.writeBlocking('[gw1]_Project Version Information/verNum4th', newVerNum)
	addVersionNote(projectArea, topic, notes)

```

My button actionPerformed event script calling the custom method is (line 39 in the image):

`event.source.incrementVerNum4th(projectArea, topic, notes)`

And the result is this error message:

`AttributeError: 'com.inductiveautomation.ignition.common.script.Imm' object has no attribute 'tag'`

I don’t get it…I thought custom method scripts were just like any other script. I check the manual ([Custom Component Methods - Ignition User Manual 8.1 - Ignition Documentation](https://docs.inductiveautomation.com/display/DOC81/Custom+Component+Methods) and [Extension Functions - Ignition User Manual 8.1 - Ignition Documentation](https://docs.inductiveautomation.com/display/DOC81/Extension+Functions)) but didn’t see any restrictions or entries in the forum that match. I even tried it with an import system statement (as seen in the extension functions document) but I get the same error. Any ideas?

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/5/05f0d2484bce82323c8301b18af4e5a80efaa360.png)

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

Thank you and regards,  
Ted.

---

<div class="post-metadata">

**Author:** ![edward.fowler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/edward.fowler/32/24179_2.png) [@edward.fowler](https://forum.inductiveautomation.com/u/edward.fowler)\
**Post date:** [June 11, 2021, 6:17pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/2 "2021-06-11T18:17:14Z")

</div>

This might help…

Traceback (most recent call last):  
File “event:actionPerformed”, line 77, in   
File “”, line 6, in addVersionNote  
AttributeError: ‘com.inductiveautomation.ignition.common.script.Imm’ object has no attribute ‘tag’

```
at org.python.core.Py.AttributeError(Py.java:207)
at org.python.core.PyObject.noAttributeError(PyObject.java:1032)
at org.python.core.PyObject. __getattr__ (PyObject.java:1027)
at org.python.pycode._pyx136.addVersionNote$1(<custom-function addVersionNote>:16)
at org.python.pycode._pyx136.call_function(<custom-function addVersionNote>)
at org.python.core.PyTableCode.call(PyTableCode.java:171)
at org.python.core.PyBaseCode.call(PyBaseCode.java:189)
at org.python.core.PyFunction. __call__ (PyFunction.java:446)
at org.python.core.PyMethod. __call__ (PyMethod.java:171)
at org.python.pycode._pyx134.f$0(<event:actionPerformed>:77)
at org.python.pycode._pyx134.call_function(<event:actionPerformed>)
```

---

<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 11, 2021, 6:33pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/3 "2021-06-11T18:33:23Z")

</div>

~~You need to call it with self.addVersionNote.~~  
Oh wait…  
Nvm

---

<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 11, 2021, 6:34pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/4 "2021-06-11T18:34:47Z")

</div>

A few things:

1.) Screen shots are really unhelpful, using the preformatted text is much better  
2.) The stack trace you posted is incomplete  
3.) The error occurs on Line 77 which isn’t visible in your screen shot.  
4.) There is no need to `import system`

Edit: 5.) The error occurs in the function `addVersionNote` which you haven’t shown

---

<div class="post-metadata">

**Author:** ![edward.fowler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/edward.fowler/32/24179_2.png) [@edward.fowler](https://forum.inductiveautomation.com/u/edward.fowler)\
**Post date:** [June 11, 2021, 6:35pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/5 "2021-06-11T18:35:03Z")

</div>

Found an almost identical reference in ["system" functions not available from client](http://forum.inductiveautomation.com/t/system-functions-not-available-from-client/28021) that refers to [Using system.\* inside a custom function? - #9 by systemparadox](http://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/9)

No sure how the work-arounds apply to my issue…trying to find out the status of ticket # 44974.

---

<div class="post-metadata">

**Author:** ![edward.fowler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/edward.fowler/32/24179_2.png) [@edward.fowler](https://forum.inductiveautomation.com/u/edward.fowler)\
**Post date:** [June 11, 2021, 6:38pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/6 "2021-06-11T18:38:31Z")

</div>

@lrose Hi, thanks for replying.  
Oh yeah, wrong stack trace, no matter though as it gives the same error calling system.tag.readBlocking.

---

<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 11, 2021, 6:39pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/7 "2021-06-11T18:39:58Z")

</div>

> [@lrose](#):
>
> There is no need to `import system`

From memory the only time you need to import system is when you define a function within a gateway scoped event with legacy scoping, or something.. Im probably completely wrong... @paul-griffith?

---

<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 11, 2021, 6:42pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/8 "2021-06-11T18:42:05Z")

</div>

The complete correct stack trace may still be helpful, as well as the script where the error is occurring.

---

<div class="post-metadata">

**Author:** ![edward.fowler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/edward.fowler/32/24179_2.png) [@edward.fowler](https://forum.inductiveautomation.com/u/edward.fowler)\
**Post date:** [June 11, 2021, 6:42pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/9 "2021-06-11T18:42:31Z")

</div>

@nminchin Hi Nick,  
Yeah, the import didn’t help, found that out (lol)

---

<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 11, 2021, 6:44pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/10 "2021-06-11T18:44:38Z")

</div>

Btw readBlocking takes an array of tags, not a string

 ![Screenshot_20210612-041549_Chrome](https://us1.discourse-cdn.com/inductiveautomation/original/3X/1/c/1c51f64eae50ff4d238f1f26cb7a31c700f42a62.jpeg)

---

<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 11, 2021, 6:45pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/11 "2021-06-11T18:45:49Z")

</div>

> [@nminchin](#):
>
> Btw readBlocking takes an array of tags, not a string

I would modify that slightly by saying tag **Paths** , but yeah.

And writeBlocking takes an array of tagPaths, and values as well.

---

<div class="post-metadata">

**Author:** ![edward.fowler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/edward.fowler/32/24179_2.png) [@edward.fowler](https://forum.inductiveautomation.com/u/edward.fowler)\
**Post date:** [June 11, 2021, 7:13pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/12 "2021-06-11T19:13:30Z")

</div>

Yes, more precisely a list of qualified values where each qualified value has three attributes (value, quality and timestamp) hence my suffix [0].value in the read instruction. I don’t think my script is an issue…the exact script works properly when I call it from the Project script library…just not in the component customer methods.

---

<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 11, 2021, 7:16pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/13 "2021-06-11T19:16:49Z")

</div>

No,

read and write blocking need a list of tagPaths. readBlocking returns a list of qualified values.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/4/d/4d71e7280fe84bd82c871a7952e92d7c59cf0890.png)

[https://docs.inductiveautomation.com/display/DOC81/system.tag.readBlocking](https://docs.inductiveautomation.com/display/DOC81/system.tag.readBlocking)

---

<div class="post-metadata">

**Author:** ![edward.fowler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/edward.fowler/32/24179_2.png) [@edward.fowler](https://forum.inductiveautomation.com/u/edward.fowler)\
**Post date:** [June 11, 2021, 7:17pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/14 "2021-06-11T19:17:10Z")

</div>

Same as my reply to Nick…  
“Yes, more precisely a list of qualified values where each qualified value has three attributes (value, quality and timestamp) hence my suffix [0].value in the read instruction. I don’t think my script is an issue…the exact script works properly when I call it from the Project script library…just not in the component customer methods.” so it must be something else…similar to what I found in ["system" functions not available from client](http://forum.inductiveautomation.com/t/system-functions-not-available-from-client/28021) ?

---

<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:** [June 11, 2021, 7:20pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/15 "2021-06-11T19:20:31Z")

</div>

Fairly recently we made a sneaky change to the read and write functions to allow single elements to be passed, since it's a common 'papercut' issue for new users and our training department. The preferred syntax is still to call it with a list, but single values are accepted - that explains the syntax in the OP working.

> [@nminchin](#):
>
> From memory the only time you need to import system is when you define a function within a gateway scoped event with legacy scoping, or something… Im probably completely wrong… @paul-griffith?

Basically correct - gateway event scripts are the only system that still uses 'legacy' scripting, and therefore needs you to reimport `system` inside any defined functions.

---

<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 11, 2021, 7:23pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/16 "2021-06-11T19:23:59Z")

</div>

> [@paul-griffith](#):
>
> Fairly recently we made a sneaky change to the read and write functions to allow single elements to be passed, since it’s a common ‘papercut’ issue for new users and our training department. The preferred syntax is still to call it with a list, but single values are accepted - that explains the syntax in the OP working.

🤔 Perhaps a note in the documentation?

Good to know though

---

<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 11, 2021, 7:36pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/17 "2021-06-11T19:36:10Z")

</div>

Please, edward, when you paste errors or code, highlight what you’ve pasted and click the preformatted text button in the comment editor’s toolbar. You can edit your comments above to do this retro-actively. Not doing this makes it hard for us volunteers to help you. ):

---

<div class="post-metadata">

**Author:** ![edward.fowler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/edward.fowler/32/24179_2.png) [@edward.fowler](https://forum.inductiveautomation.com/u/edward.fowler)\
**Post date:** [June 11, 2021, 8:15pm UTC](https://forum.inductiveautomation.com/t/attribute-error-in-component-custom-method/47712/18 "2021-06-11T20:15:45Z")

</div>

**Hello All,**

The custom method definitely (seems at least anyway) can’t reference system.tag but I found a solution (more like a work-around?) thanks to @silverbacknet (post [Using system.\* inside a custom function? - #9 by systemparadox](http://forum.inductiveautomation.com/t/using-system-inside-a-custom-function/12355/9)) where a reference to `system.tag` must be passed as an argument to the custom method. It works and is not messy.

This is my buttons actionPerformed script, see line 5 (`import system.tag as sysTag`) and the last line.

```auto
# ==========================================================================
# Commit the version notes and increment the version number...only after everything is validated.
# ==========================================================================
# The import is needed for the custom methods...refer to line 42.
import system.tag as sysTag
# The three user input fields must be validated.
projectArea = event.source.parent.getComponent('dd_projectArea').selectedStringValue
topic = event.source.parent.getComponent('ta_topic').text
notes = event.source.parent.getComponent('ta_versionNotes').text

if (projectArea == ''):
	system.gui.messageBox("You must select a project area.")
elif (topic == ''):
	system.gui.messageBox("You must enter a topic.")
elif (notes == ''):
	system.gui.messageBox("You must enter notes.")
else:
	if system.gui.confirm(
		"Are you sure you want to commit these notes and increment the version?",
		"Commit"):
			selectedVersion = event.source.parent.versionNumber
			if (selectedVersion == 0):
				event.source.forgetVersionInfo()
				system.nav.closeParentWindow(event)
				event.source.resetAllVerNums(projectArea, topic, notes)
			elif (selectedVersion == 1):
				event.source.forgetVersionInfo()
				system.nav.closeParentWindow(event)
				event.source.incrementVerNum1st(projectArea, topic, notes)
			elif (selectedVersion == 2):
				event.source.forgetVersionInfo()
				system.nav.closeParentWindow(event)
				event.source.incrementVerNum2nd(projectArea, topic, notes)
			elif (selectedVersion == 3):
				event.source.forgetVersionInfo()
				system.nav.closeParentWindow(event)
				event.source.incrementVerNum3rd(projectArea, topic, notes)
			else:
				event.source.forgetVersionInfo()
				system.nav.closeParentWindow(event)
				event.source.incrementVerNum4th(projectArea, topic, notes, sysTag)

```

This is the custom method where I was getting the error, but with a system.tag reference argument it works nicely.

```auto
def incrementVerNum4th(projectArea, topic, notes, sysTag):
	# =====================================================================
	# Increments the 4th version number (work in progress).
	# <major> . <feature> . <bug fix> . <work in progress>
	# =====================================================================
	newVerNum = sysTag.readBlocking('[gw1]_Project Version Information/verNum4th')[0].value + 1
	sysTag.writeBlocking('[gw1]_Project Version Information/verNum4th', newVerNum)
	self.addVersionNote(projectArea, topic, notes, sysTag)

```

Thank you everyone for you assistance, it so nice to have volunteers like yourselves. I’ve been Ignition’ing for about a month…maybe after 12 months I’ll have enough experience to help others 🙂  
Regards,  
Ted.
