function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion

Insufficient privileges on "null" pagereference return

I've been having this issue for a while and just cannot seem to find what the problem is. Thought it started a few API versions back, there is a post that says update from api 18 to 19. Right now my controller and VF page are api version 20. 


It doesnt happen on page load. Rather seems to only happen after a controller function has been called. Before this function completes it tasks it runs some checks. If any of the checks fail it is an error and I set a Boolean to true and a String to the error message and then return null. I use the public Boolean to know whether or not to show the error page message, and the public string is holding the message.  I've checked the field permissions on each field that is being used and they are visible but read-only. Which should be fine as I am only using them to compare.


Any thoughts?


Can you provide some of the code?


This is my controller. Appologies for some of the formatting. The error always occurs when trying to return null when "showError = true".

public class CopyAppsToExistingDevicewApprovals2 {

	public Device__c OriginalDevice {get; set;}
    public Device__c DestinationDevice;
	public Boolean showError {get; set;}
    public String ErrorMessage {get; set;}
    List<DeviceapplicationAssoc__c> devAppstoAdd = new List<DeviceapplicationAssoc__c>();
	Set<Id> appIdsAlreadyOnCopiedDevice = new Set<Id>();
	Map<Id, DeviceApplicationAssoc__c> appsOnOriginalDeviceAvailableForUseMap = new Map<Id, DeviceApplicationAssoc__c>();
	public List<Application__c> appsNotAvailableForUse = new List<Application__c>();

    public Boolean additionalCheckRequired = false;
    public List<Profile> profiles = [SELECT id FROM Profile WHERE name NOT IN ('MotoDev - SysAdmin', 'MotoDev - MotoReady Admin') ORDER BY Name];
    public Map<Id, Profile> profileIdMap = new Map<Id, Profile>([SELECT id FROM Profile WHERE name NOT IN ('MotoDev - SysAdmin', 'MotoDev - MotoReady Admin') ORDER BY Name]);
    public List<Application__c> getappsNotAvailableForUse(){
    	return appsNotAvailableForUse;
    public Boolean getshowAppsNotAvailable(){
            return true;
        return false;
	public CopyAppsToExistingDevicewApprovals2(ApexPages.StandardController controller) {
		showError = false;
		OriginalDevice = [SELECT Id, Name, Android_Release__c, Country__c, Product_Family__c, Destination_Device__c FROM Device__c WHERE Id =: controller.getId()];
		for(DeviceApplicationAssoc__c da : [select Device__c,Application__c, Application__r.Name, Application__r.Available_For_Use__c, AcctOwner__r.Name, lrb_approval__c,
			dts_approval__c, Application_Mgr_Selection_Approval__c, Confirmation_of_Budget_Royalties__c, FMD_Status_Approval__c, Partner_Manager_Checklist_Approval__c, 
			Requester_Approval__c, Conditional_Approval_Details__c, Approval_Status__c, DTS_Support__c, 
		    Include_in_BOM__c, Include_on_SD_Card__c, Specific_Requirements__c, Device_Feature_ID__c, FMD_State__c, Application_Manager__c, Past_LRB_Approval__c,
		    Past_SDS_Approval__c, Past_App_Mgr_Approval__c, Past_Budget_Approval__c, Past_Partner_Manager_Approval__c from DeviceApplicationAssoc__c  WHERE Device__c =:OriginalDevice.ID AND isDeleted = false]){
			if(da.Application__r.Available_For_Use__c != false){
				appsOnOriginalDeviceAvailableForUseMap.put(da.Application__c, da);
			} else {
				appsNotAvailableForUse.add(new Application__c(Id=da.Application__c, Name=da.Application__r.Name, Description__c=da.AcctOwner__r.Name));

	public pagereference copyapps(){
		system.debug('THIS IS UserInfo.getProfileId' + UserInfo.getProfileId());

	    //Check to see if user profile requires extra checks
	    system.debug('START copyapps');
	    	DestinationDevice = [SELECT Id, Android_Release__c, Country__c, Product_Family__c FROM Device__c WHERE Id =: OriginalDevice.Destination_Device__c];
		} catch(System.QueryException e){
			ErrorMessage = 'There is no destination device selected.';
			showError = true;
	    // Check to see if DestinationDevice doesnt have matrices
		List<AIF_Approval_Matrix__c> aifList = [SELECT Id, DTS_Approver__c, Finance_Approver__c, LRB_Approver__c  FROM AIF_Approval_Matrix__c WHERE Device_Name__c =: DestinationDevice.Id];
		List<Application_Manager_Selection_Matrix__c> amsmList = [SELECT Id, Application_Manager__c FROM Application_Manager_Selection_Matrix__c WHERE Device__c =: DestinationDevice.Id];
		if(aifList.size() != 1 || (aifList[0].DTS_Approver__c == null || aifList[0].Finance_Approver__c == null || aifList[0].LRB_Approver__c == null)){
			ErrorMessage = 'The Device you are trying to copy apps to is missing or has an incomplete AIF matrix. Please correct before continuing.';
	        showError = true;
		if(amsmList.size() != 3 || (amsmList[0].Application_Manager__c == null || amsmList[1].Application_Manager__c == null || amsmList[2].Application_Manager__c == null)){
			ErrorMessage = 'The Device you are trying to copy apps to is missing or has an incomplete Application Manager Selection matrix. Please correct before continuing.';
	        showError = true;
	    system.debug('PAST MATRIX CHECK');	    
	    // Check if DestinationDevice already has applications, show error
	    if([SELECT count() FROM DeviceApplicationAssoc__c WHERE Device__c =: DestinationDevice.Id AND CreatedById != '005400000013EXdAAM'] > 0){
	        ErrorMessage = 'The Destination Device selected already has Applications associated to it.';
	        showError = true;
	    system.debug('PAST EXISTING APP CHECK');   
	     // create list of profiles that do NOT require extra checks
	    system.debug('THIS IS UserInfo.getProfileId' + UserInfo.getProfileId());	
    	if(UserInfo.getProfileId() != '00e40000000oqQ9AAI' && UserInfo.getProfileId() != '00e40000000oqznAAA'){
            //the userprofile matches that of one that requires additional checks
            additionalCheckRequired = true;     
            if((OriginalDevice.Android_Release__c != null && DestinationDevice.Android_Release__c != null) && (OriginalDevice.Android_Release__c != DestinationDevice.Android_Release__c)){
                ErrorMessage = 'The field Release does not match between the two selected devices.';
                showError = true;
            else if(OriginalDevice.Android_Release__c == null || DestinationDevice.Android_Release__c == null){
                ErrorMessage = 'The field Release is blank on at least one of the selected devices.';
                showError = true;
            system.debug('original/copied: ' + OriginalDevice.Country__c + '/' + DestinationDevice.Country__c);
            system.debug('PAST RELEASE CHEC'); 
            if((OriginalDevice.Country__c != null && DestinationDevice.Country__c != null) && (OriginalDevice.Country__c != DestinationDevice.Country__c)){ 
                ErrorMessage = 'The field Country does not match between the two selected devices.';
                showError = true;
            else if(OriginalDevice.Country__c == null || DestinationDevice.Country__c == null){
                if(DestinationDevice.Country__c == null) {system.debug('DestinationDevice.Country is null');}
                ErrorMessage = 'The field Country is blank on at least one of the selected devices.';
                showError = true;
            system.debug('PAST COUNTRY CHECK'); 
            if((OriginalDevice.Product_Family__c != null && DestinationDevice.Product_Family__c != null) && (OriginalDevice.Product_Family__c != DestinationDevice.Product_Family__c)){
                ErrorMessage = 'The field Product Family does not match between the two selected devices.';
                showError = true;
            else if(OriginalDevice.Product_Family__c == null || DestinationDevice.Product_Family__c == null){
                ErrorMessage = 'The field Product Family is blank on at least one of the selected devices.';
                showError = true;
            system.debug('PAST PRODUCT FAMILY'); 
        if(showError = true){
        	return null;

		system.debug('PAST FIELD CHECKS');

		//*************************************************Device Applications***********************************************************************
		system.debug('LOOK FOR DEVAPPS');
		for(DeviceApplicationAssoc__c devAppAlreadyOnCopiedDevice : [SELECT Id, Device__c, Application__c FROM DeviceApplicationAssoc__c WHERE Device__c =: DestinationDevice.Id AND isDeleted = false]){
		for(Id appId : appsOnOriginalDeviceAvailableForUseMap.keySet()){
				devAppstoAdd.add(new DeviceApplicationAssoc__c(device__c = DestinationDevice.Id,Application__c = appId,lrb_approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).lrb_approval__c, dts_approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).dts_approval__c, 
				   Application_Mgr_Selection_Approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Application_Mgr_Selection_Approval__c, Confirmation_of_Budget_Royalties__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Confirmation_of_Budget_Royalties__c, FMD_Status_Approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).FMD_Status_Approval__c,
				   Partner_Manager_Checklist_Approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Partner_Manager_Checklist_Approval__c, Requester_Approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Requester_Approval__c, Conditional_Approval_Details__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Conditional_Approval_Details__c, 
				   Approval_Status__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Approval_Status__c, DTS_Support__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).DTS_Support__c, Include_in_BOM__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Include_in_BOM__c, Include_on_SD_Card__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Include_on_SD_Card__c, 
				   Specific_Requirements__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Specific_Requirements__c, Device_Feature_ID__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Device_Feature_ID__c, FMD_State__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).FMD_State__c, Application_Manager__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Application_Manager__c,
				   Past_LRB_Approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Past_LRB_Approval__c, Past_SDS_Approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Past_SDS_Approval__c, Past_App_Mgr_Approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Past_App_Mgr_Approval__c, 
				   Past_Budget_Approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Past_Budget_Approval__c, Past_Partner_Manager_Approval__c = appsOnOriginalDeviceAvailableForUseMap.get(appId).Past_Partner_Manager_Approval__c));				
			DestinationDevice.Applications_Copied_From__c = OriginalDevice.ID;
			DestinationDevice.applications_copied__c = System.NOW();	
			update DestinationDevice;
			insert devAppstoAdd;
			List<DeviceApplicationAssoc__c> newDevAppsRequiring3rdPartyApproval = [SELECT Id, X3rd_Party_Approval_Required__c, X3rd_Party_Approval_Status__c FROM DeviceApplicationAssoc__c WHERE Device__c =: DestinationDevice.Id AND X3rd_Party_Approval_Required__c = true AND X3rd_Party_Approval_Status__c = 'In Progress']; 

	    	for(DeviceApplicationAssoc__c da : newDevAppsRequiring3rdPartyApproval){
				// Create an approval request for the DevApp  
				Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
				//req.setComments('Submitting request for approval.');
					// Submit the approval request for the account  		    
					Approval.ProcessResult result = Approval.process(req);
					// Verify the result  		    
				catch(System.DmlException e){
	                ErrorMessage = 'The new DeviceApplications have been created but one or more of them that need to be re-submitted for 3rd Party Approval could not be automatically re-submitted and must be done manually.';
	                showError = true;
	                return ApexPages.CurrentPage();
		PageReference DestinationPage = new pagereference('/'+OriginalDevice.Destination_Device__c+'?returl=/'+OriginalDevice.ID);
		System.Debug(OriginalDevice.Destination_Device__c + '**********Destination Device**********');
		return DestinationPage;


The VF page:


<apex:page standardController="Device__c" extensions="CopyAppsToExistingDevicewApprovals2" >
    <style type="text/css">        

    <apex:form >    
		<apex:pageMessage rendered="true" severity="warning" strength="1" summary="You may only 'Copy to an Existing Device with Approvals' in the case that the exact same versions of 3rd Party apps will be used from the previous device to the new device.  If new versions are required (including taking bug fixes or feature changes on the app), those specific apps must go through the full approval process.  By proceeding, you are verifying that the app versions will be the same (or that you will immediately delete any apps cloned with approvals if the version is changing and manually re-add it to go through approvals).  Failure to follow these instructions properly may result in removal of your permissions to 'Copy with Approvals' and/or escalation to management."/>
        <apex:pageBlock title="Copy Device Applications To Existing Device w/ Approvals" mode="edit">

            <apex:pageMessage severity="error" strength="3" rendered="{!ShowError}" summary="{!ErrorMessage}"/>
            <apex:pageBlockButtons >
                <apex:commandButton action="{!copyApps}" value="Copy Device Applications" />
                <apex:commandButton action="{!cancel}" value="Cancel" />
            <apex:pageBlockSection title="Device information" columns="1" >
                <apex:outputField value="{!}"/>
                <apex:inputField value="{!OriginalDevice.Destination_Device__c}"/>

           	<apex:pageBlockSection title="Applications from the original Device that are not available for use and will not be copied." columns="1" rendered="{!showAppsNotAvailable}" >
                <apex:dataTable value="{!appsNotAvailableForUse}" var="app" cellpadding="2">
                    <apex:column >
                       <apex:facet name="header">Application Name</apex:facet>
                       <apex:outputLink value="/{!}" id="theLink" target="_blank">{!app.Name}</apex:outputLink>
                   <apex:column >
                       <apex:facet name="header">Account Manager</apex:facet>
                       <apex:outputText value="{!app.Description__c}" id="acctMgr"/>
                <apex:outputText styleclass="messageText" value="Contact the appropriate Account Manager if you have any questions about why an Application is no longer available for use."/>
                <apex:outputText styleclass="messageText" value="Ensure that these apps are removed from the software for the Destination Device, to make sure the acual software matches the SW BOM."/>               



This example can reproduce the error:


1) Create a custom object called Visible_Only_To_Admins__c and only allow admins to see the page.

2) Create this Page

<apex:page controller="OnlyForAdmins">
<apex:form >
<apex:commandButton action="{!go}" value="GO"></apex:commandButton>


3) Controller

public class OnlyForAdmins {

    public List<Visible_Only_To_Admins__c> admins {get;set;}
    public PageReference go() {
        admins = [select id,name from Visible_Only_To_Admins__c];
        return null;



4) Open the page as a non-admin and then click go.   You will get the Insufficient privilege error.



This is because all of the instance variables  ("admins" in this example) are saved to the View State.

The current user must have "read" access to all objects in the View State.

If the current user does not have "read" access to an instance variable, then the "Insufficent privilege" message will be shown.


I believe you are probably hitting this situation.


I recently ran across this problem and found the problem to be a class that I was instantiating in the page controller.  The page and controller were at API version 27, while the class file was at version 20.0.


Updating the class version to 27.0 fixed the "Insufficient privileges" problem.


Hope that helps others with the same problem.


- Ron