Which master-detail and required field errors will I see?
A small child object produces three messages, one per rule:
- Child object with sharing set to ReadWrite and a master-detail field:
Cannot set sharingModel to ReadWrite on a CustomObject with a MasterDetail relationship field - Lookup field marked required, no delete rule:
field integrity exception: unknown (must specify either cascade delete or restrict delete for required lookup foreign key) - Permission set with a field permission on the master-detail field:
You cannot deploy to a required field: Site_Visit__c.Account__c
The same object with sharing set to Controlled by Parent passes. So does the required lookup once it has a delete rule.
Why does the object file fail?
A child object of a master-detail relationship gets its sharing from the parent. In the object's XML, sharingModel must be ControlledByParent. Any other value fails, as in the first row.
The lookup rule is separate. A required lookup field has to say what happens to the child when the parent is deleted, so add <deleteConstraint>Restrict</deleteConstraint> or Cascade.
Why does the permission set fail?
A master-detail field is always required, and required fields cannot have field permissions in a profile or permission set file. Remove the fieldPermissions entry for that field. The same rule is behind You cannot deploy to a required field: Account.Name for standard required fields.
What about the missing parent field in a change set?
If the child object goes up without its master-detail field, the deploy breaks. Salesforce Help's fix is to include the master-detail custom field in the change set, even if you did not change it (Salesforce Help). With the Metadata API, there are two more things to know. A new master-detail field on an object that has detail records needs those records soft deleted (sent to the Recycle Bin) before the deploy. Converting a lookup to master-detail permanently deletes any detail records already in the Recycle Bin (same Help article). Plan that with the data owner, not at midnight.
How do I fix it in Setup?
- For sharing: open Setup, Sharing Settings, find the child object, and check that it reads Controlled by Parent in the source. Then deploy the object and the master-detail field together.
- For a required lookup: in Object Manager, open the field and set what happens when the parent is deleted.
- For field permissions: open the permission set in the source and remove the master-detail field from Field Permissions. The field is already visible.
- For change sets: click View/Add Dependencies, then add the master-detail field by hand if it is not listed.
- Validate again.
How do I fix it with the CLI?
Change the XML as above and send object and field together:
sf project deploy start --metadata CustomObject:Site_Visit__c --metadata CustomField:Site_Visit__c.Account__c --dry-run --test-level NoTestRun -o target-org
How do I avoid these errors?
Retrieve object, fields and permission set from the same org at the same time. Never edit a master-detail field's permissions by hand. Read the entries on master-detail relationships and lookup relationships before you convert one to the other, since the conversion has data effects. For the profile side, see profile and permission set errors. AI Salesforce deployments checks that a bundle carries the fields its objects need.
Questions about master-detail deploy errors
Can I change a lookup to master-detail with a deploy?
Yes, but the conversion permanently deletes any detail records already in the Recycle Bin, and a new master-detail field on an object with detail records needs those records soft deleted first.
Why can't I give field access to a master-detail field?
It is a required field, so access is always on. Salesforce rejects a permission entry for it in a deploy.
What does Controlled by Parent mean?
Record access on the child follows the parent record. It is the sharing model a child object needs once it has a master-detail field.
Does a required field block all my loads?
A required field must have a value on every record you insert. Add a default or supply the value in the load file.