I'm building Visualfroce for updating Custom Metadata.

When User without required permissions tries to update them he gets error message

I tried checking MetadataType__mdt.getSObjectType().getDescribe().isUpdatable(), but it returns false even for System Admin.

I know that I can query Profile and all associated Permission Sets to check if User has CustomizeApplication System Permission, but maybe there is a better way.

Please share your insights if you know of any other way to check it in Apex.


I've already implemented functionality for updating Custom Metadata using Metadata API.

This error is thrown by Visualforce if the page has and User doesn't have permission necessary to update Custom Metadata.


Custom Metadata Type records cannot be updated via direct DML like

update myCMTRecord;

by anyone, including system administrators, because that's not supported in Apex at all.

To modify Custom Metadata in Apex, you must use the Apex Metadata API to perform an asynchronous deploy operation.

The Apex Metadata API essentially passes security through to the underlying Metadata API:

Apex Metadata API deployments always respect Metadata API permissions. Although you can write Apex code that lets end users enqueue a deployment, that deployment fails if the users don’t have the correct Metadata API permissions.

which requires the Modify All Data and API Enabled permissions, or the beta Modify Metadata permission.

I'd suggest taking two tacks here:

  • Since there will soon be multiple ways to obtain access to the Metadata API, it's probably a more stable approach to expose the editing interface based on a higher-level grouping, like System Administrators only, or an org-specific permission set that you establish. Check for that qualification before allowing the user to begin editing, so that you can show a friendly error message.
  • Use a wrapper class to hold values that are intended to be persisted as a CMT record during the editing process and bind Visualforce components only to the wrapper class. This would allow you to centralize permission management in the method which initiates the metadata update or insert operation, where you'd convert those wrappers into actual CMT records to pass to Apex.
  • Thanks David for detailed response. I've already implemented functionality for updating Custom Metadata using Apex Metadata API. The question is how to handle the situation when a user doesn't have necessary permissions.
    – ytiq
    Aug 22 '18 at 11:24
  • Here what is shown in Debug Logs "04:23:18.0 (26463530)|EXCEPTION_THROWN|[EXTERNAL]|System.VisualforceException: Update access denied for External_Systems_Info__mdt, controller action methods may not execute."
    – ytiq
    Aug 22 '18 at 11:24
  • Could you please edit your question to make that context clear?
    – David Reed
    Aug 22 '18 at 11:38
  • thanks, I updated the question's description. Hopefully, it better describes the problem now
    – ytiq
    Aug 22 '18 at 11:43
  • thanks for your suggestions. I think we'll do it based on specific Permission Set
    – ytiq
    Aug 22 '18 at 13:42

I suggest querying UserPermissionAccess which only has the row of the current user:

public Boolean userCanEditMetadata() {
  UserPermissionAccess perm = [SELECT Id, PermissionsCustomizeApplication FROM UserPermissionAccess];
  return perm.PermissionsCustomizeApplication;
  • This works a treat, except for in unit tests - the perm throws an exception that the [SELECT] list was empty :/
    – zaitsman
    Apr 27 '20 at 11:35

You can't currently manipulate Custom Metadata Types from Apex as they are considered metadata.But can try using Metadata Api hoping this will work.

Updating Answer:

Before any DML operation you should check the user have permission to do this dml or not.

for this you can check isUpdateable() if this return true than do the DML operation otherwise skip it.

For instance, if a User can Create Cases, but not Edit them, then all Fields on Case will return false for isUpdateable, regardless of Field type or Field Level Security. Object security will trump.

Case.Subject.getDescribe().isAccessible() --> true; Case.Subject.getDescribe().isCreateable() --> true; Case.Subject.getDescribe().isUpdateable() --> false

  • Yes, but they still can be used in <apex:inputText> for example. And since Visualforce checks FLS it throws an error.
    – ytiq
    Aug 22 '18 at 11:30
  • thanks, but isUpdateable() is always false for Custom Metadata
    – ytiq
    Aug 22 '18 at 13:41
  • Yes, isUpdateable is always false for metadata because you can not update metadata values in apex. If above information is helpful upvote this Aug 22 '18 at 13:44

This is what we use. Works with both, Permsets and Profiles.

    public static Boolean canCreateMetadata(Id thisUserId) {
        try {
            User thisUser = [
                    FROM User
                    WHERE Id =: thisUserId];
            Integer perms = [
                    AssigneeId =: thisUserId
                    (PermissionSet.PermissionsModifyAllData = TRUE OR PermissionSet.PermissionsModifyMetadata = TRUE)
            return thisUser.Profile.PermissionsModifyAllData || thisUser.Profile.PermissionsModifyMetadata || (perms>0);
        } catch (Exception e) {
            return false;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.