1

The code in the managed package does reference ContactShare.SObjectType but changing the Account sharing to private (that in turn affects Contact) did not fix this managed package installation error:

Contacts Missing Organization Feature: Contact.Sharing

The code pushes fine into a scratch org that has default sharing settings. And in the org the install fails in select id from contactshare does run. The failing org is being created here https://developer.salesforce.com/signup. And I've also created a no-namespace org that has the same install failure.

No joy Googling for Contact.Sharing; similar category of error here Accounts Missing Organization Feature when install Managed Package with Person Account in organization without Person Account but not the same.

Any suggestions on what to try next?

4
  • Check the OWDs. Contact is not necessarily "Controlled by Parent" but can be explicitly set for itself.
    – Phil W
    Commented Feb 8 at 19:08
  • And if it is Controlled by Parent then, of course, contact sharing is disabled since it is then actually Account sharing that is in use...
    – Phil W
    Commented Feb 8 at 19:12
  • Thanks @PhilW. Current theory is that the managed package install logic (but not the unmanaged package install logic) is being tripped up by a reference to ContactShare.SObjectType in some Apex managed sharing code. Given the "Controlled by Parent" nature of Contact, perhaps the installer is looking for a non-existent "Contact.Sharing" flag somewhere. Have an install running now where all references to Share SObjectTypes are have been made dynamic not static in the package; install going OK so far.
    – Keith C
    Commented Feb 8 at 19:31
  • I was going to suggest using dynamic reference. This will allow the install (and honestly is how you should do this in managed code coz you cannot control the org setup). BUT... you can set Contact OWDs to private or public read only to have ContactShare available.
    – Phil W
    Commented Feb 8 at 20:30

1 Answer 1

0

I've now worked around this problem.

Some code that does Apex Managed Sharing included a static (compile time) reference to ContactShare.SObjectType but only for defensive error handling. The sharing for Contact is normally controlled by its parent Account. So while the code compiles, at install time of the managed package, some validation appears to be (inappropriately) checking a "Contact.Sharing" flag that is not set, perhaps because of a general algorithm applied to any share type.

The work-around I added was to make the ContactShare.SObjectType dynamically discovered (run time) and so not visible to the installation process:

    @TestVisible private static SObjectType contactShare {
        get {
            if (contactShare == null) contactShare = sobTypeForName('ContactShare');
            return contactShare;
        }
        private set;
    }

    private static SObjectType sobTypeForName(String sobTypeName) {
        Type t = Type.forName(sobTypeName);
        if (t != null) {
            // This approach avoids the big delay of a global describe
            return ((SObject) t.newInstance()).getSObjectType();
        } else {
            return null;
        }
    }

You must log in to answer this question.

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