@josephcasale -
The Basic Problem
When SailPoint IdentityNow sees that a dynamic attribute’s value is an empty string (""
), it doesn’t pass that value into the Apache Velocity environment at all. So if your VTL (Velocity Template Language) tries to do something like:
#if($bar)
The value of bar is: $bar
#end
…and $bar
happens to be an empty string, $bar
doesn’t exist at all in Velocity. That often results in an error (or unexpected behavior) because Velocity thinks $bar
was never defined.
Why “Wrapping” with a Fallback Solves It
To make sure $bar
is always defined in Velocity, you give it a fallback value when it’s empty (for example "none"
). That way, $bar
will never be truly empty—it will at least be "none"
. Then you can say in your Velocity code:
#if($bar != "none")
The value of bar is: $bar
#end
This check makes sure you only show (or use) $bar
if it’s not "none"
. By doing this, you avoid the entire “variable doesn’t exist” issue.
Concrete Example
Step 1: Use a “firstValid” Aggregator
Here’s an example transformation definition in IdentityNow (in JSON). Notice how "bar"
is defined with a firstValid
aggregator. That aggregator tries a primary value, and if that primary value is empty, it uses "none"
instead:
{
"name": "foo",
"type": "static",
"attributes": {
"bar": {
"type": "firstValid",
"attributes": {
"values": [
{
"attributes": {
"id": "Get Something"
},
"type": "reference"
},
"none"
]
}
},
"value": "#if($bar != 'none')$bar#end"
}
}
What’s happening here?
- The transformation tries to retrieve a value from
"Get Something"
.
- If that result is not empty,
$bar
ends up holding that value.
- If that result is empty, the
firstValid
aggregator says “Use the next item in the list,” which is "none"
.
Hence $bar
will always be either the real text or the string "none"
.
Step 2: Write Your Velocity Template Safely
Inside the "value"
attribute, we have this Velocity snippet:
#if($bar != 'none')
$bar
#end
- If
$bar
was a legitimate string, we’ll print it.
- If
$bar
was empty, then it becomes "none"
. The #if($bar != 'none')
check fails, so nothing prints—but crucially, we do not crash the template by referencing a non-existent variable.
Layman’s Takeaway
- IdentityNow will not pass an attribute into Velocity if the attribute’s value is empty.
- Velocity will complain (or do unexpected things) if you reference a variable that doesn’t exist.
- To fix this, use a fallback: if your dynamic attribute is empty, automatically replace it with some placeholder (like
"none"
).
- Now, Velocity always sees a real variable, so you can safely do
#if($bar != "none")
.
That’s basically why the “layer of indirection” is needed. It’s not just extra complexity for the sake of it; it’s because under the hood, IdentityNow chooses not to inject empty values into Velocity, and that can crash or confuse your template. By explicitly returning a placeholder ("none"
) instead of an empty string, your template logic stays in control and avoids errors.
Hope this helps