DateCompare transform failing with firstDate null when using accountAttribute from source Employee

Hello SailPoint Support,

We are facing an issue with an Identity Security Cloud transform used to calculate the Lifecycle State for contractor identities.

The transform is a static transform that uses two nested dateCompare transforms. Both dateCompare blocks read the same account attribute from the authoritative source “Terceiros”, attribute “endDate”.

However, during identity refresh, some identities are failing with the following error:

java.lang.IllegalArgumentException: DateCompare failed: both firstDate and secondDate must be provided. Current values: firstDate[null], secondDate[2026-05-01T00:00Z]

The error indicates that firstDate is being resolved as null, even though the transform is configured to read the account attribute Terceiros.endDate.

"type": "static",
"attributes": {
"isActive": {
"type": "dateCompare",
"attributes": {
"firstDate": {
"attributes": {
"sourceName": "Terceiros",
"attributeName": "endDate"
},
"inputFormat": "ISO8601",
"outputFormat": "ISO8601",
"type": "accountAttribute"
},
"secondDate": {
"type": "dateMath",
"attributes": {
"expression": "now-1h",
"roundUp": true
}
},
"operator": "gt",
"positiveCondition": "true",
"negativeCondition": "false"
}
},
"within45DaysAfterEndDate": {
"type": "dateCompare",
"attributes": {
"firstDate": {
"attributes": {
"sourceName": "Terceiros",
"attributeName": "endDate"
},
"inputFormat": "ISO8601",
"outputFormat": "ISO8601",
"type": "accountAttribute"
},
"secondDate": {
"type": "dateMath",
"attributes": {
"expression": "now-45d-1h",
"roundUp": true
}
},
"operator": "gt",
"positiveCondition": "true",
"negativeCondition": "false"
}
},
"value": "#if($isActive == 'true')active#elseif($within45DaysAfterEndDate == 'true')bloqueado#{else}inactive#end",
"requiresPeriodicRefresh": true
},
"internal": false
}

Expected behavior:

  1. If Terceiros.endDate is greater than current date/time minus 1 hour:
    lifecycleState should be active.

  2. If Terceiros.endDate is not active anymore, but still within 45 days after the end date:
    lifecycleState should be bloqueado.

  3. If Terceiros.endDate is older than 45 days:
    lifecycleState should be inactive

    Currently, the transform works as expected for most identities. However, some identities encounter the reported error during the Identity Refresh process.

    We have observed that when the logic related to the “bloqueado” state (the second dateCompare) is removed and only the “active” and “inactive” states are kept, the transform executes normally and the error does not occur.

    Have any ideia ?

Hi Henrique,

The error suggests that for some identities, Terceiros.endDate is actually resolving to null during refresh:

firstDate[null]

Even though most identities have a value, it only takes a few accounts with a missing, empty, or unparsable endDate to trigger the dateCompare failure.

A few things I’d check:

  • Verify the affected identities have a populated endDate on their Terceiros account.
  • Confirm the value format matches the expected ISO8601 format.
  • Check whether some identities have multiple Terceiros accounts or account correlation issues causing the attribute lookup to return null.
  • Consider wrapping the logic with a firstValid or a null-handling pattern before passing the value to dateCompare.

The reason it may work when you remove the second dateCompare is that you’re reducing the number of evaluations against a potentially null attribute. The underlying issue is likely data quality or attribute resolution rather than the comparison logic itself.

I’d start by identifying a few identities from the error logs and inspecting their aggregated endDate values directly. That should reveal whether the attribute is missing or not being resolved consistently.

Hi @henriqueoliveira2026,

I noticed several syntax issues in the transform you shared. Could you please try using the transform attached below and make any necessary adjustments before testing? I’ve also included reference documentation links for your convenience.

Account attribute | SailPoint Developer Community
Date Math | SailPoint Developer Community
Date Compare | SailPoint Developer Community

{

    "type": "static",

    "attributes": {

        "isActive": {

            "type": "dateCompare",

            "attributes": {

                "firstDate": {

                    "attributes": {

                        "input": {

                            "attributes": {

                                "sourceName": "Terceiros",

                                "attributeName": "endDate"

                            },

                            "type": "accountAttribute"

                        },

                        "inputFormat": "<Please specify the format you are getting from Terceiros Source>",

                        "outputFormat": "ISO8601"

                    },

                    "type": "dateFormat"

                },

                "secondDate": {

                    "attributes": {

                        "input": {

                            "type": "dateMath",

                            "attributes": {

                                "expression": "now-1h",

                                "roundUp": true

                            }

                        },

                        "inputFormat": "yyyy-MM-dd'T'HH:mm",

                        "outputFormat": "ISO8601"

                    },

                    "type": "dateFormat"

                },

                "operator": "gt",

                "positiveCondition": "true",

                "negativeCondition": "false"

            }

        },

        "within45DaysAfterEndDate": {

            "type": "dateCompare",

            "attributes": {

                "firstDate": {

                    "attributes": {

                        "input": {

                            "attributes": {

                                "sourceName": "Terceiros",

                                "attributeName": "endDate"

                            },

                            "type": "accountAttribute"

                        },

                        "inputFormat": "<Please specify the format you are getting from Terceiros Source>",

                        "outputFormat": "ISO8601"

                    },

                    "type": "dateFormat"

                },

                "secondDate": {

                    "attributes": {

                        "input": {

                            "type": "dateMath",

                            "attributes": {

                                "expression": "now-45d-1h",

                                "roundUp": true

                            }

                        },

                        "inputFormat": "yyyy-MM-dd'T'HH:mm",

                        "outputFormat": "ISO8601"

                    },

                    "type": "dateFormat"

                },

                "operator": "gt",

                "positiveCondition": "true",

                "negativeCondition": "false"

            }

        },

        "value": "#if($isActive == 'true')active#elseif($within45DaysAfterEndDate == 'true')bloqueado#{else}inactive#end",

        "requiresPeriodicRefresh": true

    }

}

Hi @henriqueoliveira2026,

Did you get a chance to try the transform?
Please let us know if it works.

Hello,

I tried to solve it, but in my view, dealing with lifecycle data generates errors in the identity, even though it manages to resolve the lifecycle, the identity remains with an error.

What is the error on the identity ?

Hi Henrique,

Try adding a ‘firstValid’ to this section. First value can be the endDate from Terceiros, the fallback can be 12/31/9999 (in ISO8601 format)