Thing I Learned: NPSP Contact Role Triggers
- Michael Kolodner
- Apr 30
- 5 min read
Did you know that the NPSP triggers that automate opportunity contact roles (OCRs) are essentially built on the assumption that nobody will ever manually update opportunity contact roles? I didn't know it. I knew that people would rarely do so. But I've always showed them that it could be done and left the buttons on the page to do so.

I think this is a reasonable assumption, honestly, but it's a pretty big one that has some major implications, so I'm very surprised we (the nonprofit Salesforce practitioner community) have basically never talked about it. I feel like this should be one of those things we all point out regularly so that it doesn't slip through the cracks!
What They Do
The NPSP triggers exist to automate creation of opportunity contact roles for donors, matched donors, honorees, household members, people affiliated to the organization giving a donation, or people with a relationship to the giver. In the most concrete terms, the triggers create opportunity contact roles for the people that are in several NPSP fields:
Primary Contact (on Opportunity, fieldname npsp__Primary_Contact__c) - This one's pretty easy to understand. Whoever is in the Primary Contact field will get an opportunity contact role and that role will be the one designated as Primary.
Honoree Contact (on Opportunity, fieldname npsp__Honoree_Contact__c) - Whoever is in this field will get an OCR as the Honoree. [Actually, they'll get whatever role is set in NPSP Settings>Donations>Contact Roles>Honoree Opportunity Contact Role.]
Notification Recipient Contact (on Opportunity, fieldname npsp__Notification_Recipient_Contact__c) - Gets the OCR set in NPSP Settings>Donations>Contact Roles>Notification Recipient Opp Contact Role.
If there is an opportunity that is set up as a matched donation, then the primary contact of the matched donation gets an OCR set in NPSP Settings>Donations>Contact Roles>Matched Donor Role.
And the triggers also create OCRs for people based on a few bits of logic:
Household Members - Based on the settings in NPSP Settings>Donations>Contact Roles>Household Opportunity Contact Roles, members of the household that gave the donation all get OCRs.
If a contact has an affiliation to the account that made a donation, then if there is a value in the Related Opportunity Contact Role field (on Affiliation, fieldname npsp__Related_Opportunity_Contact_Role__c) they will get an OCR of that role.
If a contact has a relationship to the primary contact of a donation and there's a value in Related Opportunity Contact Role (on Relationship, field name npsp__Related_Opportunity_Contact_Role__c), NPSP will create an OCR of that role for the related contact.
As long as you are just using those lookup fields and settings to manage opportunity contact roles, all is right with the world. The NPSP triggers will ensure that your donations will all have the OCRs as I laid them out. They're even smart and will only give any given contact a single role, based on logic for what takes priority.
So far, so good.
How They Do It
It's how the NPSP triggers actually manage those OCRs that surprised me. Essentially, the triggers wipe out and re-create all the OCRs whenever there is a change to a donation that would warrant a new look at who should have contact roles. At first glance, you might think, "That's lazy programming. They ought to loop over the OCRs and only touch the ones they need to modify."
But until the Spring '20 release Opportunity Contact Role was not a first class object, which meant there were limitations of what automations could do with them. When NPSP was being developed, therefore, the developers had to come up with workarounds. One was this compromise that NPSP wipes and re-creates all the OCRs, rather than looking at the OCRs that already exist and evaluating whether they need deletion or modification.
The [rarely stated] corollary to this compromise is that NPSP assumes that nobody ever manually creates OCRs because any OCRs that have been added to an opportunity, or auto-created ones that have been modified in some way (such as to change a role), will get wiped out if there is a change that otherwise necessitates NPSP to evaluate and create OCRs.
NPSP actually does have provision for organizations that want to manually add and modify OCRs. There is a checkbox on Opportunity called Disable Contact Role Automation (npsp__DisableContactRoleAutomation__c). Its help text states, "When selected, this field disables several aspects of NPSP Opportunity Contact Role automation, potentially resulting in incorrect or duplicate data. Refer to the product documentation for more details." In plain English: When you check that box on an opportunity, no OCRs will be auto-created for that opp. None. There is no in-between. If you check that box on an opportunity, even the Primary Contact will not get a contact role. If you leave it unchecked, any contact role you create using the New button, or any modification you make, is in danger of being wiped out.
How We Noticed This

I have a client, Modern Classrooms Project, that gets money both through fundraising and earned revenue, primarily the latter. For their earned revenue they're basically using standard Sales Cloud functionality. But on those earned revenue opportunities they use the Primary Contact field. (It's a super-handy way to immediately see who you should talk with about an opp.) When you put someone in that lookup NPSP gives them an OCR, marked Primary. Meanwhile, the sales team also adds other opportunity contact roles to the deal, keeping track of other people involved.
But since contract negotiations can take time, sometimes the primary contact will change, of course. We recently realized that if you change the primary contact on the opp, the NPSP triggers wipe out all those other OCRs that the sales team has curated. Oops!
An Easy Fix?
Clearly, it's not that big of a deal for us to fix this. We just have to ensure (thorugh a Before Save flow) that all earned revenue opportunities check Disable Contact Role Automation. That ends the danger of losing data.
If we wanted, we could leave donation opportunities to still have the NPSP OCR triggers, but we should probably, in that case, remove users' ability to make any manual OCR edits on the page.

But we also have to deal with the fact that the automation around who is in the Primary Contact lookup is now disabled. Again, this isn't a huge deal, but it's not nothing either. I see two choices:
1. Build a flow to replicate NPSP's automation around Primary Contact.
2. Teach our users that there is no contact role automation, they have to create roles for everyone.
(We'll probably go with the first option, since it's a lot more convenient for the users.)
Implications for Your Org?
Lastly, let me leave you with a "call to action": Consider your organization's use of the NPSP contact role triggers. If you have a hybrid situation, like I just described for Modern Classrooms, then you may have some work to do.
If, as I think is the case for most NPSP orgs, you just want the out-of-the-box NPSP contact role functionality, then make sure that your users can't manually manage OCRs. Take the New button off the opportunity contact roles related list. And probably also Edit, while you're at it.