How to spend 6 hours to debug one dummy profile configuration error or INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []

After first public release of my past project we have faced a trouble with existing users who use a few existing applications in a client production org. For this project we had no people resources for a good integration testing thus such bugs were not surprise for us. Usually it’s a headache when you develop a project and have to integrate it inside Salesforce org which is used for a few years. In may times you will find a set of unmanaged packages from AppExchange, some customization and some apex code which has been developed by independent teams or might be freelancer. As a result pretty often you can find a many profiles and permission sets which has been poorly configured.

That was my case. I’ve been notified that user with profile from legacy application has started to get the following error during adding an Idea:

INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []

Such error points to profile configuration troubles. In most case such troubles can be fixed in minutes. But anyway first of all we have to reproduce this error on test environment before fixing.

I logged in under this user and tried to reproduce the error. Sure, I got it. The error has came from Idea.trigger which was not in scope of project which I has developed. It might mislead greenhorn developers. So, the situation was the following: users with profile which has not been changed by me got error during his usual work with application which has not been developed or changed by me. Interesting.

Pretty fast I found that Idea.trigger from legacy application creates a new Case for every new Idea. So, my application has trigger on Case and it was the reason. I pretty quick find a place from which the error came. That was an apex method like the following:

public static Boolean isCommunityUser() {
    return Constants.PROFILE_NAME_COMMUNITY_USER.equalsIgnoreCase(
        [
            SELECT Name
            FROM Profile
            WHERE Id =: UserInfo.getProfileId()
        ].Name
    );
}

As you can see this method just querying current user profile and trying to match it with name of Community user profile. Fairly simple code in just one line and the error is here. So, I checked the profile access for sObjects which were under any DML operations, apex classes which were used by Case.trigger. The profile was OK. My mind has been freeze after this point.

Finally I tried to reproduce the trouble again and go through full execution stack. At this moment I found that Constants class has several variables like that:

public static final Set<Type> SOBJECTS_WITH_SHARING = new Set<Type>{
        Question.class,
        Idea.class,
        DocumentWrapper__c.class,
        Topic__kav.class
    };

I didn’t use this code directly in Case trigger, but this string is initialized during class initialization in static context. And ultimately that was the root of the bug. Here we have several accessing of Type class variables. And for two of them the profile has no rights. Profile has no any rights for DocumentWrapper__c custom object and for Topic__kav article type. I know that for custom object that should not be a trouble, but what about article type? I gave read right for Topic__kav article type and the error was fixed.

This bug remind a few very important things about Salesforce:

  1. You has many ways to break legacy applications in Salesforce and triggers.
  2. Perform integration testing and try to start this testing in the first iteration of development.
  3. Your application might be broken by new application which will be installed to org in future, thus you have to separate and isolate your application out of other as much as you can.
  4. Salesforce is pretty hard development environment with huge amount of pitfalls
[apex][salesforce][salesforce exception]