What is the JSON Expression to get the length of a variable in the workflows

I need to get the length of a string and I have tried both .size() and .length() and getting inconsistent (or unexpected) results

Here is what I have tried…

  1. Define a variable counter and set it to a
  2. Get all the accounts of an identity
  3. Using Serial Loop iterate through the accounts
  4. In each iteration check if the account is from a specific source.
  5. If yes, using Update Variable operator, append counter with a
  6. On the other side of the loop check how many as are there in the counter.

But I am not getting the right value with both size() and length()

Hi @iamnithesh

I’m using .length() in many of my workflows and I just reverified that it’s working correctly.

I think the issue here is with your update variable not persisting outside of the loop. I’m assuming your count is always returning 1? Could you confirm by putting another define variable step before your check for counter to determine that?

I’ve been seeing similar reports in the serial loops product news page:

If you could show your workflow (just the image) steps, that may help me determine the issue.

I just replicated what you were seeing and can confirm. It’s weird because it retains the string value, but when you use .length() on it, it’s like it’s referencing the original value, not the updated version that has gone through the loop.

Define Variable referencing a String:

Right after the previous using .length() against the same variable:
image

I encountered something similar but for integers that I was using as a counter going through a serial loop. I ended up finding a workaround using this variable $.serialLoop.succeeded - that basically returns how many End Step - Success steps occurred in the loop, so instead of you incrementing a counter everytime, you can just run End Step - Success. Then you can return End Step - Failure for everytime you don’t get a match. Once you’re out of the loop, then you can do a compare check to find out how many matches you found, sort of the same way you were going to do with the counter variable.

Blog Post I Used This:
https://developer.sailpoint.com/discuss/t/implementing-dynamic-retry-workflows-in-identity-security-cloud/214250

Thanks @trettkowski for your insights

Here is the Test Workflow

I am sending 3 emails after the serial loop

Body of Send Email - test counter

has the correct string

Body of Send Email - test length()


is 1

Body of Send Email - test size()

is 3 which is correct in this case

However second test where the counter gets updated to aa has exactly same outcome as previous case for length() and size() though counter string was aaa previously and aa now

Yes, I am seeing the same behavior you have explained. Going to try what you suggested to use “End Step” approach.

Seems like “Serial Loop” is a half cooked feature released a bit too early!! Working with Forms and Workflows still seems like we are in 90s.

Due to the issue I posted in this Use {{$.place.Holders}} as a part of JSONPath to read a variable in Workflows I had to create a workflow with individual steps instead of running them in the Loop with around 5 blocks per iteration and 18 iterations, which resulted in having around 90 blocks in the workflow. This resulted in the workflow to hang forever validating every time I clicked some item. Something that would take a minute would take 15 minutes as the page would not respond. Funnily when I downloaded the workflow it was just 40 kB, where as maximum limit is 400kB for the workflow json files. I can’t even imagine how would it handle workflows of size 400kB

Sounds good. I think both our posts are on the same page.

I’m fairly certain this is a bug, but no one from SailPoint has addressed it in the product news post or in my support ticket yet, so I’m going to assume this is a feature :slight_smile:

I’ll update my ticket with this information to show it’s occurring with strings that are converted to integers as well, rather than just integers.

Thanks for bringing this up!

Serial Loops and Update Variables have some issues, but from what I understood, what you’re trying to achieve — wouldn’t it be better to use a Define Variable with a JSONPath? For example:

$.getAccounts.accounts response:

[
  {
    "id": "1e598e6100734c648d49b3347878a7bf",
    "sourceId": "36b8f6f3b5c44d5abdd4f6d42ed77f0d"
  },
  {
    "id": "428d516aa27e4f0aa98d325a402b1291",
    "sourceId": "7cf2ae7365ab45f48a25b23f49ebb89c"
  },
  {
    "id": "4602d2c1adf34c3c8c54ed6d6b6a3dc9",
    "sourceId": "b7430ae65f4c42c38a29220c5354e769"
  },
  {
    "id": "d527f63bcf11491aa49a7f6e54176961",
    "sourceId": "86b292bf765e4a329b6a60fcf95464c8"
  },
  {
    "id": "e86cb3e8709b4b75b740e93560d0f60e",
    "sourceId": "f2e4ca8fd84f472786b5301d2a394da1"
  }
]

With a Define Variable you can create a JSONPath like:

$[?(@.sourceId == '36b8f6f3b5c44d5abdd4f6d42ed77f0d' || @.sourceId == '7cf2ae7365ab45f48a25b23f49ebb89c')]

This will output an array with 2 objects, and then you define another variable with length(). Of course, if you have too many sources it will get a bit unwieldy, but you can create multiple variables with JSONPath for different source IDs and sum them up at the end!

Will only have a problem when the list returns just one item. For some reason, when using JSONPath on a list and the result is just one item, SailPoint handles it differently from standard JSONPath behavior.

Normally, JSONPath would return a list with a single item — so length() would return 1. But in SailPoint, if the filter matches only one item, instead of returning a single-element array, it returns a plain JSON object. This means you can’t use length() on it anymore, and would need to use size() instead.

So basically:

  • 2 or more results → returns an array → use length()
  • 1 result → returns a plain JSON object → use size()

That exactly will be an issue in my use case. Purpose of the workflow is to check for a duplicate account received from the auth source and send a notification to admins. I think for this my original idea is a simple and clean approach, ie if the components of the workflow work the way they should :smiley:

I tried this approach and seeing another strange behavior.

Serial Loop runs only twice where as there are 12 items in the input array

Serial Loop:

Does it exit after a Failure End Step here? Second execution results in Failure

Loop: runs 12 times with same input

I see what you mean. Just tried this in my own tenant.

What I suggested won’t work because a failure is basically a break loop as you’ve seen… I love serial loops… :upside_down_face:

Alright, another workaround! Use a regular loop instead lol!

Just tested this and it appears to work great using this to check how many items were successful since regular loops don’t break when a failure occurs!

You can see my test worked below using this variable to validate how many matches occurred:
$.loop.loopOutput.successfulItems.length()

Array Values

Comparison In Loop

Check After Loop

Valid Execution

Assuming that this duplicated account would be correlated to an identity, you have the option to call the accounts API filtering by identityId and sourceId. This would return an array and you would be able to see how many accounts an identity has in this specific source! (I don’t like this idea, but I think it would avoid the huge workflow that you mentioned.)

I totally agree that your approach is simpler and cleaner.

Eventually I followed this approach and it works for my use case.

I wanted to try out new Serial Loop option here though :smiley:

For your original approach of the “append ‘a’ char to string to get something like ‘aaa’”… (i.e. assuming you want to stick with string manipulation to get the count).

What you can try is this:
Define the string variable with initial value of “x”.
Prepend (instead of append), some dummy char (but not ‘x’), say, ‘_’.

After the first iteration, you would get ‘_x’.
After the third iteration, you would get ‘___x’.

Do a get index of ‘x’.

That’s a clever workaround. I tried implementing that and it works!

Still kind of stupid that length() doesn’t work, but I’ll take this!

Here’s my test workflow if you want to see how I implemented. I had to do a regex to get the prepend to work correctly on the update variable step.

testworkflow1220260626.json (4.1 KB)

haha…it’s a game of number representation. This is just bringing it back to a fundamental one-dimension linear number line / offset representation.

All great ideas!! Thanks everyone

In way it is a good thing the .length() did not work and we had an opportunity to have some fun :smiley: