Check for duplicte account name

<Field displayName="Application Name" dynamic="true" name="applicationName" postBack="true" required="true" type="Application"/>

<Field displayName="Enter New Service Account Name" dynamic="true" name="ServiceAcctName" postBack="true" required="true" type="string">
<Attributes>
<Map>
<entry key="hidden">
<value>
<Script>
<Source>
import sailpoint.object.Field;

              Field f8 = form.getField("accountType");
              String f8value = f8.getValue();
              boolean hideField = false;

              if (!("Service Account is type of NPA that is used by an automated process and is not used in an interactive way by a user".equalsIgnoreCase(f8value))) {
              hideField = true; 
              field.setRequired(false);
              } else {
              field.setRequired(true);
              }
              return hideField;
            </Source>
          </Script>
        </value>
      </entry>
    </Map>
  </Attributes>
  <Script>
    <Source>
      import sailpoint.tools.Util;
      String savedValue = Util.isNotNullOrEmpty(ServiceAcctName) ? ServiceAcctName : "SVC-";
      return savedValue;
    </Source>
  </Script>
  <ValidationScript>
    <Source>
      import java.util.regex.Pattern;
      import java.util.regex.Matcher;

      String regex = "(?i)Admin|Adm|Administrator|Root|Privileged|Priv|Super|Power|Pwr|PA|HPA|[@#\\$%&amp;*_=+ ]";
      Pattern pattern = Pattern.compile(regex);
      Matcher matcher = pattern.matcher(value);

      if (matcher.find()) {
      return "Input String contains Non-Allowed Special Characters or SubStrings";
      }

      if (value.length() > 20) {
      return "Length of Input should not be greater than 20";
      }

      if ("SVC-".equals(value)) {
      return "Input cannot be just 'SVC-'. Please provide a more specific name.";
      }

      return null;
    </Source>
  </ValidationScript>
</Field>

Above is the code of two field in Sailpoint identity IQ environment form. In “ServiceAcctName” field I have added few filters, and need to add one more filter which will check that the application selected in field “applicationName” does not have any account with the same name as entered by user in “ServiceAcctName”.

I tried adding code but its getting stuck in between and giving warning that Application is not selected but actually I have selected application.

Below is the code I have tried but did not work. Any suggestions to improve this.

<ValidationScript>
  <Source>
    import java.util.regex.Pattern;
    import java.util.regex.Matcher;
    import sailpoint.object.QueryOptions;
    import sailpoint.object.Filter;
    import sailpoint.object.Link;
    import java.util.List;

    // Validate restricted words and special characters
    String regex = "(?i)Admin|Adm|Administrator|Root|Privileged|Priv|Super|Power|Pwr|PA|HPA|[@#\\$%&*_=+ ]";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(value);

    if (matcher.find()) {
      return "Input String contains non-allowed special characters or substrings.";
    }

    if (value.length() > 20) {
      return "Length of input should not be greater than 20 characters.";
    }

    if ("SVC-".equals(value)) {
      return "Input cannot be just 'SVC-'. Please provide a more specific name.";
    }

    // Retrieve application name safely
    Object appField = form.get("applicationName");
    String selectedAppName = (appField != null) ? appField.toString().trim() : "";

    if (selectedAppName.isEmpty()) {
      return "Please select an application before entering a service account name.";
    }

    // Get SailPoint context
    if (context == null) {
      return "Error retrieving SailPoint context.";
    }

    // Check if the entered service account name already exists in the selected application
    QueryOptions qo = new QueryOptions();
    qo.addFilter(Filter.eq("application.name", selectedAppName));
    qo.addFilter(Filter.eq("nativeIdentity", value));

    List links = context.getObjects(Link.class, qo);
    if (links != null && !links.isEmpty()) {
      return "The entered service account name already exists for the selected application. Please choose a different name.";
    }

    return null;
  </Source>
</ValidationScript>

Hi @pctripathi,

A few observations:

  1. Instead of
    Object appField = form.get("applicationName");
    shouldn’t it be
    Object appField = form.getField("applicationName");
    ?
  2. Instead of
    appField.toString().trim() : "";
    use
    appField.getValue().trim() : "";
  3. Try to include some System.out.println to check the values that you are retrievent and make sure they are not null. For example,
    System.out.println(appField.toXml())

Hi @angelborrego
Tried as you suggested, its working but my form is getting further without checking the filter criteria i.e. If given name is the same as one of the accounts existing in the selected application.
Instead it is meant to give a warning under that field.

Try adding a System.out.println(value); in your form validation script to capture the actual value being passed. Then, use that value in a separate test rule to verify how it behaves with your previous code:

// Check if the entered service account name already exists in the selected application
    QueryOptions qo = new QueryOptions();
    qo.addFilter(Filter.eq("application.name", selectedAppName));
    qo.addFilter(Filter.eq("nativeIdentity", value));

Additionally, you can include:

int counter = context.countObjects(TaskResult.class, qo);
System.out.println("Links found: " + counter);

This will help confirm whether the query is actually finding an account.

Keep in mind that sometimes the nativeIdentity of a link isn’t exactly the same as the userId of the account —it might include additional attributes like CN=...OU=.... This could be why your filter isn’t returning any results. Double-check how the identity is stored and formatted in the system.

Hi @angelborrego
From where can I check the print statement?

In the SailPoint Identity IQ logs. If you don’t already know your log file route you can check it following these instructions.

Also, the default route for catalina logs is /home/spadmin/tomcat/logs/catalina.out

Hi @angelborrego
I actually do not have access for that. Can’t check the logs. Only errors.

Hi @pctripathi,

If you don’t have access to the logs, you can try debugging in other ways:

  1. Use UI-based debugging – Instead of relying on System.out.println(), you could display debug information directly in the UI. For example, you can temporarily modify your validation script to return debug values:
    return "Selected Application: " + selectedAppName + " | Entered Value: " + value;
    This will allow you to see the values directly in the error message under the field.
  2. Check the identity details – Go to the Identity Warehouse and manually search for an account with the name you are testing. Sometimes the issue is with how the account name is stored (e.g., extra spaces, different casing, or additional attributes like CN=).
  3. Test with a different approach – Instead of using context.getObjects(Link.class, qo), try running a similar filter in a different script (e.g., an IdentityIQ rule) and print the results to an attribute that you can view in the UI.

Since you only have access to errors, debugging becomes tricky, but these approaches might help narrow down the issue. Let me know what you find!

Hi @pctripathi,

Just checking in to see if my response helped you.

If the solution resolved your issue, could you mark it as the accepted answer in the forum? This would help others facing similar challenges and also allow me to continue progressing on my journey as a SailPoint Ambassador.

Let me know if you need further assistance!

// New validation logic to check for duplicate account names
          String applicationName = form.getField("applicationName").getValue();
          if (applicationName != null) {
          // Fetch the Application object
          Application application = context.getObject(Application.class, applicationName);
          if (application != null) {

          // Query for accounts (Links) in the selected application with the same nativeIdentity (case-insensitive)
          QueryOptions qo = new QueryOptions();
          qo.addFilter(Filter.eq("application", application));

          // Convert both the nativeIdentity and the input value to lowercase for case-insensitive comparison
          qo.addFilter(Filter.like("nativeIdentity", value.toLowerCase()));

          List links = context.getObjects(Link.class, qo);

          if (links != null &amp;&amp; !links.isEmpty()) {
          return "The service account name '" + value + "' already exists in the selected application. Please choose a different name.";
          }}
1 Like