Users with 'delegated_developer' role get a blank screen upon login if a duplicate permission set exists for any assigned application scopeIssue Users with the 'delegated_developer' role but not the 'admin' role can face a blank screen when logging in due to an incorrect permission set configuration. How it works A new role is created for each permission set that is granted to a delegated developer for each application scope. There should be a maximum of 13 (as of today) distinct permission sets per application if there are duplicates the login will fail to complete. These permission sets are saved to the 'sys_scope_permission_set_role_assignment' table. Permission sets consist of 2 reference fields: sys_development_permission_set - predefined development permissionssys_user_role - A role is created and assigned specifically for this scope and permission set in this format: sn_dd_<APPLICATION SCOPE>_<PERMISSION SET NAME>_rc_01 If a duplicate permission set is created for the same scope then the delegated_developer (without Admin role) will face a blank screen when logging in. This is because the duplicate keys cause the immutable map object used to check permissions to fail and throw the below stack trace: 2019-05-10 01:12:22 (658) AMB_SEND-thread-5 63A3798E3719B7409D8C1A7943990EFE txid=ef4b354a3759 SEVERE *** ERROR *** Multiple entries with same key: =<APPLICATION SCOPE HERE> and =<APPLICATION SCOPE HERE>java.lang.IllegalArgumentException: Multiple entries with same key: =<APPLICATION SCOPE HERE> and =<APPLICATION SCOPE HERE> at com.google.common.collect.ImmutableMap.checkNoConflict(ImmutableMap.java:136) at com.google.common.collect.RegularImmutableMap.checkNoConflictInKeyBucket(RegularImmutableMap.java:98) at com.google.common.collect.RegularImmutableMap.fromEntryArray(RegularImmutableMap.java:84) at com.google.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:295) at com.glide.sys.security.delegateddev.ScopePermissionSetRoleAssignment.loadRoleNamesFromDb(ScopePermissionSetRoleAssignment.java:154) at com.glide.sys.cache.TypeSafeCacheManager.get(TypeSafeCacheManager.java:85) at com.glide.sys.security.delegateddev.ScopePermissionSetRoleAssignment.scopesForRoleNames(ScopePermissionSetRoleAssignment.java:97) at com.glide.sys.security.delegateddev.scoperoleescalation.EscalatableRoles.getEscalatableRolesForEnvironment(EscalatableRoles.java:22) at com.glide.sys.security.delegateddev.scoperoleescalation.ScopeRoleEscalationAccessHandler.hasRightsTo(ScopeRoleEscalationAccessHandler.java:28) at com.glide.sys.security.CompositeAccessHandler.hasRightsTo(CompositeAccessHandler.java:52) at com.glide.sys.security.ContextualSecurityManager.eval(ContextualSecurityManager.java:703) at com.glide.sys.security.ContextualSecurityManager.hasRightsToImpl(ContextualSecurityManager.java:624) at com.glide.sys.security.ContextualSecurityManager.hasRightsTo(ContextualSecurityManager.java:590) at com.glide.sys.security.ContextualSecurityManager.hasRightsTo(ContextualSecurityManager.java:572) at com.glide.processors.AProcessor.isACLAuthorized(AProcessor.java:645) at com.glide.processors.AProcessor.isProcessorACLAuthorized(AProcessor.java:636) at com.glide.processors.AProcessor.processTransaction(AProcessor.java:206) at com.glide.processors.ProcessorRegistry.process0(ProcessorRegistry.java:178) at com.glide.processors.ProcessorRegistry.process(ProcessorRegistry.java:167) at com.glide.ui.GlideServletTransaction.process(GlideServletTransaction.java:31) at com.glide.sys.Transaction.run(Transaction.java:2091) at com.glide.amb.server.AMBTransaction.run(AMBTransaction.java:25) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Example This is an example of a 'broken' permission set: This situation was achieved by manually deleting the role from the 'sys_user_role' table without cleaning up the corresponding permission set from 'sys_scope_permission_set_role_assignment'.