We have an expression rule that has not been modified since 2017. The developer who wrote the rule originally is no longer with the company. This rule is executing without error in our DEV, UAT, and PRODUCTION environments.
However, when I go to the rule in Appian Designer, it's throwing an error, saying there is an undeclared local variable.
Indeed, there is an undeclared local variable, and it is referenced multiple times in the rule. However, this rule is somehow working, otherwise we would see dozens of errors in Production on a daily basis (according to the rule's Performance Trends, it's hit several hundred times a day).
How is this rule able to work correctly when it's called in Production, but becomes a problem when it's being modified in Appian Designer.
It's worth noting that the rule is called by an Interface that (again) has not been updated since 2017, and still uses "load" and "with" instead of "a!localVariables" - and the interface works perfectly, until I change the "load" to "a!localVariables", and then it returns the same expression error I'm seeing in the expression rule of an undeclared local variable.
Example code for Expression Rule (note this is just the affected code):
=load(local!QuestionDetails: if(rule!IsNullOrEmpty(local!TriggerQuestion),{},local!TriggerQuestion.QuestionId),local!QuestionDetails)
Discussion posts and replies are publicly visible
Sub-rules and interfaces inherit variables declared in the parent, presuming the variable is in scope. This used to be more standard (sadly) before practices were solidified to "require" local variables be passed via rule inputs to child items. I'm guessing that the parent of your example declares "local!TriggerQuestion" validly. I'm unsure why switching it to a!localVariables() causes the behavior to change, other than that perhaps it's more sensitive to alerting us about this sort of sloppy coding.
Thank you Mike, yes, that was the issue, it was being declared in the parent rule so when the child rule was being called, it was still within scope, though that wasn't obvious at the time. It does make sense though. But the switching from "load" to "a!localVariables" is still confusing, but not within the scope of the change I'm attempting to make.