Skip to content

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.

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.

The trap on a standard object, before Winter '27 The trap on a standard object, before Winter '27. One: a private account, and code that wants to share it with a user. Two: on AccountShare, the only row cause code can use is Manual. Three: the owner changes, and the share is removed. Four: code tries the Team row cause instead, and the insert is refused. Five: the only way out is a trigger on the owner change that writes the shares again. Footnote: on custom objects, a reason of your own always kept the share; on standard objects, it couldn't, until Winter '27. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.58.0", "built": "2026-11-03", "id": "DGM-SVA-PS-05", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "flow/sequence 0.1.0", "theme": "stevetecharc 1.4.0"} A private account code shares it with a user The user can see it. Only Manual allowed on AccountShare No reason of your own on a standard object. The owner changes the share is removed The user loses the account. Try Team instead the insert is refused Salesforce's row causes aren't yours to write. A trigger puts it back the workaround On every owner change, write the shares again. 1 2 3 4 5 STA 4.16, ON AN ACCOUNT On custom objects, a reason of your own always kept the share. On standard objects, it couldn't, until Winter '27. HOW TO READ IT 1 the order a step the step that matters most what comes next © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

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.

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.

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.”

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.

Two Winter '27 answers, and when to use each Two Winter '27 answers, and when to use each. Keep Manual Shares when Transferring Records: one org-wide setting in Sharing Settings; manual shares survive owner changes; use it when people share by hand and no code creates shares; it changes how every manual share behaves. A custom row cause on a standard object: deployed through the Metadata API, API version 68.0 and later; up to 10 per standard object; kept on owner changes; code's shares stay separate from people's and show their reason; use it when code, a flow or an integration creates shares. Footnote: Salesforce's advice: no code, use the setting; code, use a reason of your own. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.58.0", "built": "2026-11-03", "id": "DGM-SVA-PS-06", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "comparison 0.5.0", "theme": "stevetecharc 1.4.0"} Keep Manual Shares an org-wide setting Turned on in Sharing Settings Manual shares survive owner changes For shares people make by hand A custom row cause API version 68.0 and later Deployed through the Metadata API Up to 10 per standard object Kept on owner changes, with its reason For code, flows and integrations Salesforce's advice: no code, use the setting. Code, use a reason of your own. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

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.

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.

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.

STA 4.16 · Salesforce Security Apex Sharing on Standard Objects Lost on Owner Change · 12:26 · published 2023-12-06 · plays from YouTube when you click it · Watch on YouTube · More videos: Salesforce Security Architecture Videos
  • 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.