# switchLogin Script from client event keeps throwing error

**URL:** <https://forum.inductiveautomation.com/t/switchlogin-script-from-client-event-keeps-throwing-error/93662>\
**Category:** General Discussion\
**Created:** [July 24, 2024, 12:34pm UTC](https://forum.inductiveautomation.com/t/switchlogin-script-from-client-event-keeps-throwing-error/93662 "2024-07-24T12:34:30Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Caleb\_Iwen](https://avatars.discourse-cdn.com/v4/letter/c/82dd89/32.png) [@Caleb\_Iwen](https://forum.inductiveautomation.com/u/Caleb_Iwen)\
**Post date:** [July 24, 2024, 12:34pm UTC](https://forum.inductiveautomation.com/t/switchlogin-script-from-client-event-keeps-throwing-error/93662/1 "2024-07-24T12:34:30Z")

</div>

I'm running a script in my program that will switch the login to a default login after a certain time period, and although it does exactly what it's supposed to, (logs out and in correctly) it throws an error: Error running function from fpmi.system.invokeAsynchronous or fpmi.system.invokeLater (I've tried both) with the details: TypeError: 'bool' object is not callable

The script looks like this:  
currentUser=system.security.getUsername()

import system.util  
import time  
import system.security

print(currentUser)

try:  
if currentUser != "u\*\*\*\*\*\*":  
try:  
time.sleep(5)  
system.util.invokeAsynchronous(system.security.switchUser("u\*\*\*\*\*\*\*\*", "p\*\*\*\*\*\*\*\*\*"))  
except Exception as e:  
system.util.getLogger("AutoLogOut").warn("Error in invokeLater: " + str(e))  
except Exception as e:  
system.util.getLogger("AutoLogOut").warn("Error in invokeLater: " + str(e))

using asterisks in place of user/pword info. Ideally, I'd like it to not throw any errors, but I can't figure out what the issue even is, I've tried many different workarounds.

---

<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 24, 2024, 12:40pm UTC](https://forum.inductiveautomation.com/t/switchlogin-script-from-client-event-keeps-throwing-error/93662/2 "2024-07-24T12:40:05Z")

</div>

`system.util.invokeAsynchronous` requires a bare function object. No parenthesis. If you are on recent version of Ignition, you can give your function args and keyword args to `invokeAsynchronous` for it to deliver inside the new thread. If that isn't available, you have to use closures or `functools.partial` to create a temporary callable that embeds your arguments. Search this forum for `later.py` for utility functions that produce suitable closures.

The error you are getting is that your function is running **before** the thread is spawned (because you included parens), and its **return value** is what is being given to `invokeAsynchronous`.

---

<div class="post-metadata">

**Author:** ![Caleb\_Iwen](https://avatars.discourse-cdn.com/v4/letter/c/82dd89/32.png) [@Caleb\_Iwen](https://forum.inductiveautomation.com/u/Caleb_Iwen)\
**Post date:** [July 24, 2024, 12:48pm UTC](https://forum.inductiveautomation.com/t/switchlogin-script-from-client-event-keeps-throwing-error/93662/3 "2024-07-24T12:48:42Z")

</div>

Would the parenthesis cause the same issue on invokeLater? I'd prefer to use that one for simplicity, left it as async because it didn't change behavior. I'm kind of confused on the parenthesis though, the autofill for the invoke functions both include parenthesis so I'm not quite sure which ones you're referring to. Thanks either way.

---

<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 24, 2024, 12:50pm UTC](https://forum.inductiveautomation.com/t/switchlogin-script-from-client-event-keeps-throwing-error/93662/4 "2024-07-24T12:50:12Z")

</div>

Yes, same requirement for `invokeLater`. Study the examples in the manual.

To summarize:  
To run this function:

```python
somePackage.someFunction(1, 2, arg3, arg4, arg5=5, arg7=23)

```

in a background thread, you do this:

```python
system.util.invokeAsynchronous(somePackage.someFunction, [1, 2, arg3, arg4], {'arg5': 5, 'arg7': 23})

```

Note the **absence** of parentheses after `someFunction`.

---

<div class="post-metadata">

**Author:** ![Caleb\_Iwen](https://avatars.discourse-cdn.com/v4/letter/c/82dd89/32.png) [@Caleb\_Iwen](https://forum.inductiveautomation.com/u/Caleb_Iwen)\
**Post date:** [July 24, 2024, 1:26pm UTC](https://forum.inductiveautomation.com/t/switchlogin-script-from-client-event-keeps-throwing-error/93662/5 "2024-07-24T13:26:01Z")

</div>

So if I understand correctly we have:

```python
currentUser=system.security.getUsername()

import system.util
import time
import system.security

print(currentUser)

def switchUname(uname, pword):
	system.security.switchUser(uname, pword)
try:
	if currentUser != "uname":
		try:
			time.sleep(5)
			system.util.invokeLater(switchUname, ["uname", "pword"],{})
		except Exception as e:
			system.util.getLogger("AutoLogOut").warn("Error in invokeLater: " + str(e))
except Exception as e:
	system.util.getLogger("AutoLogOut").warn("Error in invokeLater: " + str(e))

```

Unfortunately, this has no effect on the program. It no longer throws an error, but it also doesn't actually swap the user as it did before.

---

<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 24, 2024, 1:33pm UTC](https://forum.inductiveautomation.com/t/switchlogin-script-from-client-event-keeps-throwing-error/93662/6 "2024-07-24T13:33:47Z")

</div>

`invokeLater` cannot pass arguments like `invokeAsynchronous`. You **must** use closures or default args in a temporary function, or use `partial()`.

Other notes:

- Your indentation seems borked. (Maybe?)

- Any sleep needs to be inside a background task. Sleep must never be used directly in a Vision event, nor in an `invokeLater` function.

- Your error checking needs to also be inside the delegated function.

Please go find `later.py`, look at its code, and examples, and examples of `invoke*` all over this forum.
