Code's Shares That Survive an Owner Change
Module 3 of 6 in the chapter Programmatic Sharing: Apex and Flow Managed Sharing, chapter 11 of Securing Salesforce: Sharing and Visibility. Each module stands on its own.
The question this module answers: Code’s shares on an account used to disappear when the owner changed. What do you do about it today?
Module 2 showed the difference on a custom object: a share with the Manual row cause is removed when the owner changes, and a share with a reason of your own stays. On custom objects, that’s been true for a long time. On standard objects, accounts, cases, opportunities, it wasn’t. This module is that story, and what changed in October 2026.
The question that sent me to an org
Section titled “The question that sent me to an org”I was teaching a Sharing and Visibility class, explaining that code has to give every share a reason, and that standard objects didn’t let you create one. A student asked: if you’re forced to use the Manual reason on an account, won’t those shares be lost on an owner change?
I wasn’t sure. So I set up an org with a private account model, and tried it.
- A manual share, made by hand. Change the owner: gone. As expected.
- A share written by code. On an account, the only row cause I could use was Manual. Change the owner: gone. It makes sense once you see the word Manual, but it surprised me.
- A share written by code with the Team row cause. Not allowed. The insert failed.
- An account team member, added by code. Change the owner: also wiped.
So we were trapped. The only way out was a trigger listening for the owner change, putting the shares back in again with the same logic that created them. And if an integration was pushing share records in from outside, it had to do the same.
In class I’d put it as a question to the room: if you create a bunch of shares from code on accounts with the Manual reason, and the owner changes, what happens to all your hard work? Lost.
What changed
Section titled “What changed”Salesforce’s own Sharing team wrote it up in October 2026: “For over a decade, standard objects didn’t support custom row causes. When you needed to share a record from Apex, you had to use the Manual row cause,” and “you had to write workarounds” (Protect Apex Shares: Custom Row Causes on Standard Objects (opens in a new tab), Salesforce Developers blog, checked 2026-11-07).
Two changes came with Winter ‘27 (same post):
- Keep Manual Shares when Transferring Records. An org-wide setting in Sharing Settings, “available now.” With it on, “Manual shares then survive ownership changes.”
- Custom row causes for standard objects. “Rolling out now; all orgs will have it by the end of October.” You “can now define one on a standard object the same way you do on a custom object.” And “You can also assign a custom row cause in Flow.”
The reference agrees. A sharing reason now “is used to indicate why sharing was implemented for a standard or custom object,” and “Sharing reasons for standard objects are available in API version 68.0 and later” (SharingReason (opens in a new tab), Metadata API Developer Guide, checked 2026-11-07). That’s the Winter ‘27 API version.
Salesforce gave the rollout a date. Before you build on it, confirm it in your own sandbox: deploy a reason on Account, write a share with it, change the owner, and query the row.
How you create one on a standard object
Section titled “How you create one on a standard object”On a custom object, you still create the reason in Classic (module 2). On a standard object, “Apex sharing reasons aren’t created from a detail-page related list. Create them by deploying a sharing reason component through the Metadata API” (Sharing a Record Using Apex (opens in a new tab), Apex Developer Guide, Winter ‘27, checked 2026-11-07).
In the object’s metadata, the reason is a name and a label:
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata"> <sharingReasons> <fullName>Key_Account__c</fullName> <label>Key Account Team</label> </sharingReasons></CustomObject>List it in the package.xml as a SharingReason member, Account.Key_Account__c. One thing to know: this type doesn’t accept the * wildcard in the manifest, so name each reason (SharingReason). Then your code uses it the same way as on a custom object:
AccountShare share = new AccountShare();share.AccountId = accountId;share.UserOrGroupId = groupId;share.AccountAccessLevel = 'Edit';share.OpportunityAccessLevel = 'Read';share.CaseAccessLevel = 'None';share.RowCause = Schema.AccountShare.RowCause.Key_Account__c;Database.insert(share, false, AccessLevel.SYSTEM_MODE);Change the account’s owner, and this row stays. In the share table, an admin sees Key Account Team as the reason, not Manual.
The rules that come with it
Section titled “The rules that come with it”From the SharingReason reference (checked 2026-11-07):
- Which objects. Standard objects “that have a corresponding share object (for example, AccountShare, OpportunityShare) and whose org-wide default can be set to Private or Public Read-Only.” A detail in a master-detail relationship has no share object, so it isn’t supported.
- How many. “You can create a maximum of 10 custom sharing reasons per standard object.” Ten is plenty for a design with one reason per rule. It isn’t enough for a reason per team or per region. That’s a sign you’re putting data in the reason.
- Which names. Reserved row cause names, “for example, Manual, Team, Sharing Rule, Record Collection,” can’t be used.
- The label. Up to 40 characters, and it’s what admins read in the Reason column.
- Deleting one is destructive. “Deleting a sharing reason deletes all share records on that object that use the reason. This can revoke access for users, so treat deletion as a destructive change.” Put a reason’s deletion through the same review as deleting a field.
- In a package. Sharing reasons can go in second-generation managed packages. In the customer’s org, the reason is locked, and “Uninstalling a package that contains sharing reasons deletes those reasons and all associated shares.”
Which of the two to use
Section titled “Which of the two to use”Salesforce’s own advice is short, and I agree with it: “If you don’t create shares in code, turn on Keep Manual Shares when Transferring Records. It’s one org-wide setting. If code, a Flow, or an integration creates shares on standard objects, switch to a custom row cause” (Protect Apex Shares).
Why not just turn on the setting and let code keep using Manual? Because a custom row cause “keeps your Apex shares separate from users’ manual shares,” lets admins “see why each user has access,” and lets you “update or delete the shares for one reason without touching the others” (same post). With Manual, your code’s rows and people’s rows look the same. You can’t tell your code’s work from a person’s when it’s time to clean up.
Test knowledge. For years, the answer was that code sharing a standard object could only use the Manual row cause, so its shares were removed when the owner changed, and the fix was a trigger on the owner change. Since Winter ‘27 (API version 68.0), standard objects with a share object can have up to 10 custom sharing reasons, deployed through the Metadata API, and their shares are kept on an owner change. Exams and study material can lag behind a release, so know both, and know which date each one belongs to. A likely area, not a known question.
Reviewing the code you already have
Section titled “Reviewing the code you already have”Salesforce’s advice ends with the first step: “Start by reviewing the code that creates CaseShare, AccountShare, or other standard share records” (Protect Apex Shares). In an older org, look for:
- Code, flows and integrations that write standard share rows with the Manual row cause.
- The workaround triggers: code that listens for an owner change and writes the shares back.
- Integrations that push share records in through the API, and what they do after an owner change.
Then plan the move: create the reason, write the new rows with it, and remove the workaround. Removing the old Manual rows your code wrote is the hard part, because the row cause doesn’t say who wrote them. Decide how you’ll find yours before you delete anything, and test with real users before and after.
Watch it on video
Section titled “Watch it on video”In 2023 a student’s question sent me to an org, and I made a video of the answer: on an account, code’s shares and the team member both went when the owner changed. The note under the video says what’s still right and what’s changed since.
What an architect decides here
Section titled “What an architect decides here”- For each standard object your code shares: a custom row cause, named for the rule it applies, within the 10.
- Whether the org also needs Keep Manual Shares, for the shares people make by hand.
- Which workaround triggers and integration steps can be retired, and in what order.
- How reasons are deployed and who may delete one, since deleting a reason removes its shares.
- How the change is proved: the old owner-change problem replayed in a sandbox, with real users.
Beyond the exam: what AI changes. AI assistants learned from years of code and forum answers that say standard objects only take Manual. Ask one for account sharing code today, and it may write Manual shares plus an owner-change trigger, a workaround that’s no longer needed. Tell it the API version you’re on, point it at the SharingReason reference, and check the row cause in what it writes. Chapter 20 covers agents.
Explore
Section titled “Explore”- Protect Apex Shares: Custom Row Causes on Standard Objects (opens in a new tab), Salesforce Developers blog, October 2026 (checked 2026-11-07)
- SharingReason (opens in a new tab), Metadata API Developer Guide (checked 2026-11-07)
- Sharing a Record Using Apex (opens in a new tab), Apex Developer Guide, Winter ‘27 (checked 2026-11-07)
