I have a Visualforce Page that uses a standard controller (Opportunity) and an extension. In the extension I have a method that saves updates to the opportunity and a related contact. The extension is "without sharing", also any other class that may be called.

When I try to save with a "normal" user profile (i.e. not System Administrator), I receive this error:

"system.security.NoAccessException: Update access denied for RecordType, controller action methods may not execute"

When I give this user's profile the "Customize Application" system permission (which is needed to update Record Types), the save works. But I don't want to do this in production, of course.

There seems to be no place in the code where record types are updated, and it is "without sharing" anyway, so I suspect the error to be originating from some system code, but I can't even see it in any debug logs, because no log is produced when I click on "Save" on the VisualForce page.

Any help will be greatly appreciated ;-)

1 Answer 1


With a little googling and some help from Salesforce support, I finally came accross a workaround. I would like to share it, in case anybody else comes accross this problem:

In my VF page (using std. opportunity controller and a custom extension), there was a hidden input with a relationship query like this:

<apex:inputHidden value="{!Opportunity.RecordType.Name}"/>

When the page initiated an update on the opportunity, SF was throwing the error "system.security.NoAccessException: Update access denied for RecordType" (which is weird, since I was not trying to update record types). By giving the permission to "Customize Application" to the executing user's profile, this error was indeed avoided, but I didn't want to go this route for obvious reasons.

In the end, the workaround was simple: delete the hidden input from the VF page, and move the selection of the record type name to the custom controller extension's constructor. In this way, the record type name is retrieved in my custom code instead of a relationship query in the standard controller, and everything works fine.

The moral of the story: Beware of relationship queries in hidden fields!

  • 2
    The real issue is you were trying to have the controller fetch relationship fields via use of inputHidden. But since inputHidden implies setting a value, you get the permissions error. If you had used an apex:variable that referenced the record type.name, the controller extension would have fetched the value without any permissions issue.
    – cropredy
    Commented Jan 24, 2016 at 23:07
  • Yes, you are right. I also figured that out later, but forgot to update this post, so thanks for pointing it out. The inputHidden was being used as a shortcut for making the value available via automatic selection in the standard controller, but I have since realised that this is bad practice. An outputHidden would have been better, but unfortunately it doesn't exist, since it doesn't really make sense ;-)
    – Mehmet B.
    Commented Jan 26, 2016 at 9:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .