Unable to find the approval assignment

Hello,

I have written an approval assignment rule as a requirement can’t be fulfilled by OOTB approval. It has been generating an error unable to find the approval assignment. Could anyone please help me understand where I have gone wrong?

I have been getting the following error on running the same:

2023-08-16T23:51:31,502 ERROR http-nio-8080-exec-3 sailpoint.server.ScriptletEvaluator:143 - Step call threw an exception:
2023-08-16T23:51:31,527 ERROR http-nio-8080-exec-3 sailpoint.server.ScriptletEvaluator:144 - sailpoint.tools.GeneralException: Unable to find the approval assignment sailpoint.object.ApprovalSet@c91057b
        at sailpoint.workflow.IdentityApprovalGenerator.buildCommonApprovals(IdentityApprovalGenerator.java:882)
        at sailpoint.workflow.IdentityApprovalGenerator.buildCommonApprovals(IdentityApprovalGenerator.java:898)
        at sailpoint.workflow.IdentityLibrary.buildCommonApprovals(IdentityLibrary.java:4231)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at sailpoint.server.ScriptletEvaluator.doCall(ScriptletEvaluator.java:134)
        at sailpoint.server.ScriptletEvaluator.evalSource(ScriptletEvaluator.java:63)
        at sailpoint.api.Workflower.evalSource(Workflower.java:5932)
        at sailpoint.api.Workflower.expandApproval(Workflower.java:6401)
        at sailpoint.api.Workflower.start(Workflower.java:6277)
        at sailpoint.api.Workflower.advanceApproval(Workflower.java:6057)
        at sailpoint.api.Workflower.advanceStep(Workflower.java:5146)
        at sailpoint.api.Workflower.advance(Workflower.java:4558)
        at sailpoint.api.Workflower.startCase(Workflower.java:3144)
        at sailpoint.api.Workflower.launchSubcase(Workflower.java:5474)
        at sailpoint.api.Workflower.launchSubcases(Workflower.java:5367)
        at sailpoint.api.Workflower.advanceStep(Workflower.java:5158)
        at sailpoint.api.Workflower.advance(Workflower.java:4558)
        at sailpoint.api.Workflower.startCase(Workflower.java:3144)
        at sailpoint.api.Workflower.launchSubcase(Workflower.java:5474)
        at sailpoint.api.Workflower.launchSubcases(Workflower.java:5390)
        at sailpoint.api.Workflower.advanceStep(Workflower.java:5158)
        at sailpoint.api.Workflower.advance(Workflower.java:4558)
        at sailpoint.api.Workflower.startCase(Workflower.java:3144)
        at sailpoint.api.Workflower.launchInner(Workflower.java:2813)
        at sailpoint.api.Workflower.launch(Workflower.java:2666)
        at sailpoint.api.Workflower.launchSession(Workflower.java:2536)
        at sailpoint.api.IdentityLifecycler.launchUpdate(IdentityLifecycler.java:144)
        at sailpoint.api.IdentityLifecycler.launchUpdate(IdentityLifecycler.java:152)
        at sailpoint.service.RequestAccessService.runWorkflow(RequestAccessService.java:1508)
        at sailpoint.service.RequestAccessService.submitRequest(RequestAccessService.java:444)
        at sailpoint.rest.ui.requestaccess.RequestAccessResource.submitRequest(RequestAccessResource.java:90)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:475)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:397)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
        at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234)
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)
        at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at sailpoint.web.SailPointResponseFilter.doFilter(SailPointResponseFilter.java:76)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at sailpoint.rest.jaxrs.MethodOverrideFilter.doFilter(MethodOverrideFilter.java:90)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at sailpoint.rest.RestCsrfValidationFilter.doFilter(RestCsrfValidationFilter.java:71)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at sailpoint.rest.AuthenticationFilter.doFilter(AuthenticationFilter.java:109)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at sailpoint.web.SailPointContextRequestFilter.doFilter(SailPointContextRequestFilter.java:61)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at sailpoint.web.SailPointPollingRequestFilter.doFilter(SailPointPollingRequestFilter.java:151)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at sailpoint.web.ResponseHeaderFilter.doFilter(ResponseHeaderFilter.java:63)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:673)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.base/java.lang.Thread.run(Thread.java:834)

Here is the rule I have run with:

import sailpoint.object.Workflow;
	import sailpoint.object.Workflow.Approval;
	import sailpoint.object.newApprovals;
	import sailpoint.object.Identity;
	import sailpoint.object.Application;
	import sailpoint.object.ManagedAttribute;
	import sailpoint.object.Custom;
	import sailpoint.object.ApprovalItem;
	import sailpoint.tools.GeneralException;
	import sailpoint.object.Attributes;
	import sailpoint.api.SailPointContext;
	import sailpoint.object.IdentityItem;
	import sailpoint.api.SailPointFactory;
	import sailpoint.query.Condition;
	import sailpoint.object.QueryOptions;

	public static String getADSecurityGroupOwner(String adSecGroup) throws GeneralException {
		// Query the custom object by name "ADSecurityGroupsOwners"
		Custom customObject = context.getObjectByName(Custom.class, "ADSecurityGroupsOwners");
		
		// Fetch the owner name based on the AD security group name from the custom object
		if (customObject != null) {
		  System.out.println("Initializing ADSecurityGroupsOwners");
			Attributes customAttributes = customObject.getAttributes();
			String owner = (String) customAttributes.get(adSecGroup);
			System.out.println("******************Custom Owner= " + owner);
			if (owner != null) {
				return owner;
			}
		}
		// Return null if the custom object or the specified AD group is not found
		
		return null;
	}

	// Helper method to fetch the value from the custom object "ADSecurityGroupsOwners"
	public static String getADSecurityGroupId(String adGroupName) throws GeneralException {
		// Query the custom object by name "ADSecurityGroupsOwners"
		Custom customObjectId = context.getObjectByName(Custom.class, "ADSecurityGroupID");
		// Fetch the owner name based on the AD security group name from the custom object
		if (customObjectId != null) { 
		  System.out.println("Initializing ADSecurityGroupID");
			Attributes customAttributesId = customObjectId.getAttributes();
			String adGID = (String) customAttributesId.get(adGroupName);
			System.out.println("******************adGID= " + adGID);
			if (adGID != null) {
				return adGID;
			}
		}
		// Return null if the custom object or the specified AD group is not found
		
		return null;
	}


	try {
		// Validating newApprovals
		System.out.println("******************ApprovalSetCurrent = " + approvalSet.toXml());
		if (newApprovals != null) {
			ApprovalSet newApprovals = new ApprovalSet();
			// Fetch Approval Items from newApprovals
			List<ApprovalItem> aItems = approvalSet.getItems();
			if (aItems != null){
				// Iterating through ApprovalItems from newApprovals
				for (ApprovalItem aItem : aItems) {
					System.out.println("******************aItem = " + aItem.toXml());
					if (aItem != null) {
						// Fetch the application name of the ApprovalItem
						String app1 = aItem.getApplicationName();
						Application app = context.getObjectByName(Application.class, app1);
						System.out.println("******************Application Name = " + app);
						// if the application name is equal to AD perform the block
						if (app1 != null && app1.equalsIgnoreCase("AD")) {
							String adGroupName = aItem.getDisplayValue();
							adGroupName=adGroupName.replace("\\","\\\\");
							//System.out.println("******************ADGroup = " + adGroup1 + value);
							String adGroupID = getADSecurityGroupId(adGroupName);
							System.out.println("******************Printing GroupID = " + adGroupID);
							ManagedAttribute adGroup = context.getObjectById(ManagedAttribute.class, adGroupID);
							System.out.println("******************ADGroup = " + adGroup);
							if (adGroup != null) {
								String groupType = adGroup.getAttribute("GroupType");
								System.out.println("******************ADGroup Type = " + groupType);
								if (groupType != null) {
									if (groupType.toLowerCase().contains("security")) {
										String adSecGroup = adGroup.getDisplayName();
										adSecGroup=adSecGroup.replace("\\","\\\\");
										System.out.println("******************AD Group Display Name = " + adSecGroup);
										String ownerName = getADSecurityGroupOwner(adSecGroup);
										System.out.println("******************AD Group Custom Owner Name = " + ownerName);
										if (ownerName != null){
											System.out.println("******************ApprovalItem = " + aItem);
											System.out.println("******************ApprovalItemPriorChange = " + aItem.getOwner());
											aItem.setOwner(ownerName);
											System.out.println("******************ApprovalItemOwner = " + aItem.getOwner());
											newApprovals.add(aItem);
										} else {
											System.out.println("****************** Custom object Owner*************** Custom object owner could not be resolved");
										}
									} else {
											aItem.setOwner(adGroup.getOwner());
											newApprovals.add(aItem);
									}
								}
							}
						} else if (app1 != null && app1.equalsIgnoreCase("healthds")){
							aItem.setOwner(app.getOwner());
							newApprovals.add(aItem);
						} else {
							String aItemOwner = aItem.getOwner();
							if (aItemOwner != null){
								aItem.setOwner(aItemOwner);
								newApprovals.add(aItem);
							} else {
								aItem.setOwner(app.getOwner());
								newApprovals.add(aItem);
							}
						}
					}
				}
				return newApprovals;
			}
		}
	} catch (GeneralException e) {
		// Handle the GeneralException (or any other exception) here
		System.out.println("Error: " + e.getMessage());
		e.printStackTrace();
	}

Thank you!

I’d suggest initializing a default/fall-back owner for ApprovalItems to prevent a null owner and see if that resolves the exception. Odds are there’s something in there with no owner/mapping that will be discovered based on finding things assigned to the fall-back owner that you were expecting to be assigned to someone else.

hi @sreeram
As far as I can see you are validating newApprovals value but it has not been declared before

// Validating newApprovals
if (newApprovals != null) {
...
}

Maybe do you refer to param approvalSet?

From other side, you are importing the following object wrongly

import sailpoint.object.newApprovals;

Hi Brian,

Thank you for the quick response. I set the fallback approver and the issue persisted.

Hi Ismael,

Thank you for the response. I have rectified them as pointed out. The issue was resolved up on setting the approvalScheme as ‘manager, owner’ and approvalSplitPoint as ‘owner’.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.