Incorrect Value Passed on Boolean Type as an Input/Output Argument

Hello,

In my attached workflow zip file, I have encountered incorrect value passed on a input/output argument using Boolean and Boolean array.

In my Main Workflow _Test.xaml, I have two variables: one is Boolean Type and one is Boolean array Type. They are set by default as false.

In my 2nd Workflow _Test2.xaml, which is invoked in the main, Im passing the two variables as input/output argument. There, I will set the value of Boolean Type = True and Boolean[0] array Type = True then i will throw an exception.

In the Main workflow, I will now print the value of I/O arguments to check the current value of the local variables which came from the 2nd workflow, in which I encounter incorrect results.

Expected Result:
Boolean Type: True
Boolean[0] Array Type: True

Actual Result:
Boolean Type: False
Boolean[0] Array Type: True

Can anyone check what would be the cause of the issue? is this a bug?

Boolean Argument.zip (3.4 KB)

2 Likes

Hi @Emman_Pelayo

This is interesting, I’ve tried it myself and it is an unusual behavior.

So if we don’t have the throw activity inside the invoked test2 workflow, everything is working fine and the finally write line give the expected results, but when we have the throw activity, only the boolean inside the array is giving us the expected result (True) and the boolean variable doesn’t get assigned, which is weird.

To make sure that it wasn’t the in/out factor that leads the variable to not get assigned I created an out bool variable to make sure that we will have the same problem and sure enough it was the same problem.

I think we should tag UiPath team for this one :
@loginerror
@ovi
please look at this.

Regards,
Reda

1 Like

Yes reda :frowning:. I had encountered this while tweaking the retry mechanism for application exception via reframework template.

I have a transaction item which is save in different webpages thus needs to set a success flag for every page should an app error happens in the middle and then will just continue on the failed parts.

Data types is not likely the cause too as it fails for string and string array scenario.

1 Like

Hi @Emman_Pelayo

you’re saying it’s the same thing for other types (fail for string - but work as expected for string[]) ?

Yes reda. Arrays saves me though. I spent several hours investigating the issue but to no avail. I thought the reframework caused this too but managed to replicate it in a simple flow.

I think this post can be helpful (the entire thread as well):

It is an interesting discovery though that the array arguments are actually returned in this scenario.

2 Likes

I tested this using a Boolean OUT argument, and the result I got was that it still failed to return the value back to the main - which by the way is expected when an exception is thrown.

Here is how I set up the test:

First image is to store values to the array that will be invoked, then Throw an exception:

Second image is where I Invoked the file surrounded by a Try/Catch:

If I disabled throwing the exception, the Boolean was returned (as it should). However, if I Throw the exception the array is not returned - refer to error message:
image

@Emman_Pelayo
Perhaps, you initialized your array to a value prior to Invoking the workflow file that threw an exception. Or maybe there is some other reason for your result?

Regards.
@loginerror @reda

Hi Clayton,

You can check my attached zip file containing the test. You are correct on that i had initialized the value of the boolean array. Same thing for the boolean type too, but with different results.

Yes. I just looked at your workflow closer and you are outputting the values in the Finally. So, the Finally must be functioning in a way that allows the Array values to be returned. So, that is interesting.

Let me point out also that if you assign the values like this:
image
They don’t get returned.

But, if you assign them individually like this:
image

Then, it gets returned.

EDIT:
I then removed it from the Finally, and it still resulted the same. So, it’s not the Finally. It’s how the values are being stored in the array.

2 Likes

Finally seems not be the cause. Note that it is just a test workflow. I have worked this in reframework while monitoring the value on the exit of process state and it works the same way.

Well if this works, maybe it can work on single value variables too :joy:

Thanks Clayton.

1 Like

I also tested this using a For Each to assign the values to the array and they were not returned.

However, if I used a Do While using a counter for the index, then they were returned:
image

To be honest though, I don’t see how this would be practical for most arguments - my interest in this though is you can return some information from the invoked workflow such as WorkFlow file name for example.

As i stated in my previous response, the purpose is to set success flags for the retry mechanism wherein my transaction item involves different webpages that is connected to each other (First Page: Data Entry then Save to database; 2nd Page: Tag the ID of First Page Record (Filled in a dropdown), Data entry then save to database. So if there is an application error occurs for example in the second page, It will just base on the success flags pass as arguments during the retry.

1 Like

Any update on this why array works instead of boolean types only? Seems datatable works also too. Maybe it is related how the value/s are passed. Something like Boolean Datatypes were passed by values and Arrays/Datatables were passed by reference/address?

1 Like

You’re correct, this is a value type/reference type difference.

As was mentioned here (and in the linked thread), when a workflow errors out the arguments are not assigned back.
BUT, with reference type (which Array and DataTable are examples of) what gets passed is a memory address (pointer). Changes within the child workflow operate on the same memory space, so it’s not really that they’re passed back, but that the values are changed “underneath” (on the heap).

This video (and the Part 2 of it) might explain it better than I can:

When you use bool[] arrayVariable = {True, False, True} there’s a new object constructed, which gets allocated in a difference memory address. This is because the { something } syntax is actually a shorthand for an array initializer. If we expand the code to how a compiler sees it it’s actually something like this:
bool() io_arr = New bool() From { True, False, True }
Since the variable now points to a different memory address, all changes are done there and do not overlap with the original array. If the workflow completes, it will pass back the new memory address to which the original array should point to.
The old values are actually still there, although now unreferenced, and will be collected by garbage collector. If you have another variable in main that before the invoke gets the same reference (so arrayCopy = io_arr and the workflow will complete, they will actually NOT be the same object anymore.

This topic might be actually interesting for an article… :contemplatesLackOfTime:

5 Likes