BeanShell scripts in SailPoint IdentityIQ are often used to transform identity data, especially inside connector rules like BuildMap or Customization rules. These scripts help generate values like display names, emails, or special flags (think: IIQDisabled, IIQLocked). But there’s a catch—assuming all fields are always populated is like assuming every pizza has cheese. 🍕

This post breaks down two common gotchas: null references and uninitialized variables (hello, void).

💣 The Null Trap

Let’s say you’re trying to log the manager’s name and email for a user. Sounds simple?

// Look up spadmin and log manager details
import sailpoint.object.Identity;
String idName = "spadmin";
Identity id = context.getObjectByName(Identity.class, idName);
if (null == id) {
  log.error("Could not find Identity record named: " + idName);
  return;
}

Identity mgr = id.getManager(); // Uh-oh
String mgrFirstName = mgr.getFirstname();
String mgrLastName  = mgr.getLastname();
String mgrEmail     = mgr.getEmail();

log.debug("mgrFirstName:[" + mgrFirstName + "] + mgrLastName: [" + mgrLastName + "]");

If spadmin has no manager set, this code will crash and burn with a classic NullPointerException. And BeanShell won’t even tell you where it broke—line 0, thanks for nothing.

✅ The Right Way to Handle Nulls

import sailpoint.object.Identity;
String idName = "spadmin";
Identity id = context.getObjectByName(Identity.class, idName);
if (null == id) {
  log.error("Could not find Identity record named: " + idName);
  return;
}

Identity mgr = id.getManager();
if (null == mgr) {
  log.error("Could not find a manager Identity record for: " + idName);
  return;
}

String mgrFirstName = mgr.getFirstname();
String mgrLastName  = mgr.getLastname();
String mgrEmail     = mgr.getEmail();

log.debug("mgrFirstName:[" + mgrFirstName + "] + mgrLastName: [" + mgrLastName + "]");

Note the style: if (null == mgr). It’s not just a quirk—this helps avoid accidental assignment in if statements and works across many languages (Java, C, Perl…).

🫥 Uninitialized Variables and the Mystery of void

In BeanShell, a variable that’s declared but not yet initialized gets the special value void. This is different from Java, where every variable must have a declared type and value. BeanShell is more chill… but that flexibility can bite you.

Use case: newer IIQ versions pass a taskResult variable to rules triggered by Task executors. Older versions don’t. So how do you write code that runs in both?

boolean inTaskContext = false;
if ((void != taskResult) && (null != taskResult)) {
  inTaskContext = true;
}

Checking for void ensures backward compatibility and avoids those “why is this null again?” headaches.

🛠️ Recap: Best Practices

Need help transforming identity data safely in your IIQ rules? Start with these checks—you’ll sleep better at night and avoid the dreaded line: 0 curse.

Got other BeanShell horror stories or tips? Drop them in the comments. Let’s turn pain into power. 💪