I am building some maps to compare which profiles have access to which fields.

In doing this I need to compare the results of a FieldPermissions query against all available fields as there is not a field permission record if the profile does not have read access.

I get all available fields through .getDescribe():

SObjectType objectType = Schema.getGlobalDescribe().get(objectToFetch);
Map<String,Schema.SObjectField> allFields = new Map<String,Schema.SObjectField>(); 
allFields = objectType.getDescribe().fields.getMap();

[[[fieldPermissionList queried here]]]

for (FieldPermissions fieldPermission : fieldPermissionList) {

    String pureFieldName = fieldPermission.Field.replace(objectToFetch + '.', '');

    if (allFields.get(pureFieldName) != null) {
        allFields.remove(pureFieldName); <-- Collection is read only external entry point error here. 

Why is the collection read only?

1 Answer 1


The field map from a describe is a special map that is read-only. This property is important, as describe calls are cached, so if you modified the cache, you'd get unpredictable behavior in other parts of code. The immutability of the map makes sure you don't accidentally cause side-effects elsewhere in your code.

If you want to make a copy, you could:

Map<String,Schema.SObjectField> allFields = 
  new Map<String,Schema.SObjectField>(

Note that this removes the special property of having case-insensitive keys, though, which may have other side effects. Be careful when using the maps this way. Otherwise, you may want to otherwise create a new map and add the values you want to keep to that map, instead.

You must log in to answer this question.

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