Can someone help me identify why my entry is invalidating?
getContent() will return the element’s ContentModel, NOT getContent()-&gt;merchant, which is just an attribute of the ContentModel—sorry for the confusion.

I’ve just posted a separate Q&amp;A fully explaining what the ContentModel is used for here:

What is getContent() / the ContentModel, and how do I use it to get and set custom field values?

What you are experiencing is actually a slight bug in Craft’s validation logic. Relational fields have a feature where their data is not actually required to be in POST when saving an entry. If that’s the case (if their value in the ContentModel ends up just being null), then they will simply not make any changes to the element’s relationships - the field value will be left untouched.

However the ContentModel is not aware of that feature, and it’s the ContentModel that is currently in charge of enforcing Required Field validation. So, when it gets to your relational field, and finds that its value is null, it gives you a validation error rather than letting it slide.

So, you have two workaround options, if you want to keep the data the same, but need the field to be required:


You can actually set the value based on the current value:

$entry-&gt;setContentFromPost(array(
    // ...
    'merchant' =&gt; $entry-&gt;merchant-&gt;ids(),
));

craft()-&gt;entries-&gt;saveEntry($entry);

If all you’re doing is changing custom field values (nothing entry-specific) and you’re comfortable skipping custom field validation altogether, you can just call ContentService::saveContent() directly, and pass in false to its second argument which tells it to skip validation:

$entry-&gt;setContentFromPost(array(
    // ...
    'merchant' =&gt; null, // Tells the relational field to keep the old value
));

craft()-&gt;content-&gt;saveContent($entry, false);