Skip to main content
October 30, 2025
Solved

Array with no items but length still ] 0

  • October 30, 2025
  • 16 replies
  • 1 view

Hello, again.

This is a strange one.... and I'm on version 24.1.281.0

I have two expression rules... one generates some error messages (or none) and the other deals with the errors.  However, in the scenario where the first expression rule generates no errors, the second one still thinks there are errors.

Expression 1: (called SH_ErrorGenerator)

a!localVariables(
  local!stringArray: {"a", "b"},
  local!error1: "",  /* value from another expression rule normally */
  local!error2: "",  /* value from another expression rule normally */
  local!error3: {""},  /* value from another expression rule normally */
  local!errors: {
    local!error1,
    local!error2,
    local!error3
  },
  local!allErrors: cast(  /* make sure this is list of string not list of variant */
    typeof(local!stringArray),
    reject(a!isNullOrEmpty, a!flatten(local!errors))
  ),
  local!anyErrors: and(not(isnull(local!allErrors)), length(local!allErrors) > 0),
  {
    errors: local!allErrors,
    anyErrors: local!anyErrors
  }
)

Expression 2:

a!localVariables(
  local!result: rule!SH_ErrorGenerator(),
  local!errors: local!result.errors,
  local!anyErrors: and(not(isnull(local!errors)), length(local!errors) > 0),
  local!anyErrors
)

Here is the result I see.

result.anyErrors (calculated by SH_ErrorGenerator) is false (as it should be), but local!anyErrors (calculated by second rule) says true.  And even the local variables screen says there are 0 items in the array.

Any idea what's going on here?

Thank you.

Best answer by shubhama926776

Appian treats lists with empty strings as having length, but they cannot be indexed.
Use a!isNullOrEmpty() to check for real errors instead of length().

16 replies

October 30, 2025

A small tweak shows the second expression sees the array as having 1 element.

a!localVariables(
  local!result: rule!SH_ErrorGenerator(),
  local!errors: local!result.errors,
  local!anyErrors: and(not(isnull(local!errors)), length(local!errors) > 0),
  {
    a: local!anyErrors,
    b: length(local!errors)
  }
)

But, of course, you cannot actually index that item.

a!localVariables(
  local!result: rule!SH_ErrorGenerator(),
  local!errors: local!result.errors,
  local!anyErrors: and(not(isnull(local!errors)), length(local!errors) > 0),
  {
    a: local!anyErrors,
    b: length(local!errors),
    c: local!errors[1]
  }
)

October 30, 2025

I’ve tried to replicate your case, and it seems that when you’re indexing the value “local!result.error”, it’s returning a list of variants. That’s why you’re getting the error you mentioned.

October 31, 2025

Actually, your scenario does not faithfully represent my code above.  You are, indeed, using an array of variant by specifying {} without any qualification.  I explicitly cast my data to List<string> (see first code segment above).

I don't think this will repro without using 2 expression rules.  As I showed in my example, within the first expression rule, it does, rightly, know the array is empty.  It's not until it is returned to the calling expression rule that the weirdness ensues.

shubhama926776
October 31, 2025

Appian treats lists with empty strings as having length, but they cannot be indexed.
Use a!isNullOrEmpty() to check for real errors instead of length().

October 31, 2025

And yet, within SH_ErrorGenertor length() did return 0.  Why does it sometimes return 0 and sometime return 1 for the same value?

October 31, 2025

You are correct in that isNullOrEmpty does return true in this case.  

harshas2775
October 31, 2025

The expression for local!anyErrors in expression 2 checks if error is not null as well as its length. Though the local!errors is having 0 items yet as the function length("") returns 1. So length will return true. Similarly behavior of isnull() can be understood from below. 


not(isnull({""})) returns true
not(isnull("")) returns false

 length("")   /*returns true*/
not(isnull({""})) /*returns true with a List of empty string*/
not(isnull("")) /*returns false with empty string*/

Given the behavior and working of isnull() and length() the value for local!anyErrors in expression 2 seems fine. To properly check and correct the behavior as per your requirement I suggest you to either replace the local!anyErrors definition with a!isNotNullOrEmpty(local!errors) or simply use local!result.anyErrors. 

local!anyErrors: a!isNotNullOrEmpty(local!errors) or,
local!anyErrors: local!result.anyErrors /* Either of these*/

October 31, 2025

I'm not looking for a string to be empty.... I'm looking to see if an array is empty.  Why would length(someArray) be 1 if there are no items in the array?  That doesn't make any sense.

October 31, 2025

You are correct in that isNullOrEmpty does return true in this case.  

stefanhelzle0001
October 31, 2025

In this blog post, I try to cover how to check for empty data.

https://appian.rocks/2022/10/17/the-magic-of-null-checking/

October 31, 2025

What I learn from your blog is essentially that I should be using isNullOrEmpty (the same thing everyone else here is saying).  I don't have a need for the edge cases you mention, but it is good info to know about.