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’.

1 Like

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