Populate the fields in the brackets. To stop fixing them one at a time, enumerate every create-required field on the object with Schema.DescribeFieldResult — isNillable() == false and isCreateable() == true and isDefaultedOnCreate() == false — and put all of them in your test data factory once.
Where this check runs
The error comes from system validation, and its position in the order of execution is the detail that decides your options:
1. Record loaded, defaults applied
2. before insert / before update triggers <- can still populate the field
3. System validation (required fields, field
lengths, field types, foreign key integrity) <- REQUIRED_FIELD_MISSING fires here
4. Custom validation rules <- too late; never runs
5. Duplicate rules, save to database
6. after insert / after update triggersSo a before-insert trigger can default the field and prevent the error — it runs first. A validation rule cannot help and will not even be reached. And an after-trigger is far too late: the row never got to step 5.
One asymmetry between insert and update. On insert, a required field that is absent or null fails. On update, only fields you explicitly include in the record and set to null fail — omitting a field from the update record leaves the stored value alone and is fine. This is why "blanking a field" is its own distinct bug.
The six reasons a field is required, ranked
1. A schema-required standard field
Built into the object, not configurable, and the reason most test data factories fail on their first run. The list worth memorising:
- Contact —
LastName. - Opportunity —
Name,StageName,CloseDate. - Lead —
LastName,Company. - Case — nothing by default, which surprises people the other way.
- Task / Event —
StatusandPriorityon Task;DurationInMinutesandActivityDateTimeon Event. - ContentVersion —
Title,PathOnClient,VersionData. - ContentDocumentLink —
LinkedEntityId,ContentDocumentId. - User — the big one:
Alias,Email,LastName,Username,ProfileId,EmailEncodingKey,LanguageLocaleKey,LocaleSidKey,TimeZoneSidKey.
2. An empty master-detail relationship field
A master-detail lookup is implicitly required regardless of what its own metadata says — a detail record cannot exist without its master. It also cannot be given a default value, so there is no trigger-side escape: the parent Id has to be supplied by the caller.
// Fails: REQUIRED_FIELD_MISSING, Required fields are missing: [Invoice__c]
insert new InvoiceLine__c(Amount__c = 100);
// Insert the master first, then the detail with the parent Id
Invoice__c inv = new Invoice__c(Name = 'INV-001');
insert inv;
insert new InvoiceLine__c(Invoice__c = inv.Id, Amount__c = 100);The same shape catches bulk factories: building 200 children before inserting the parent leaves every child's lookup null. Insert parents, then map child to parent Id, then insert children.
3. A custom field marked Required in the field metadata
The distinction that costs the most debugging time:
- Required on the field definition (
<required>true</required>in the field's metadata, or the "Required" checkbox when editing the field) enforces at the database layer. It applies to Apex, the API, data loads — everything. This produces REQUIRED_FIELD_MISSING. - Required on a page layout is a UI affordance only. Apex and the API ignore it completely. If a field is layout-required and your Apex still fails, the field is also metadata-required and the layout setting is a red herring.
4. A Universally Required field added after the tests were written
Someone ticks Required on an existing custom field and every test factory that predates it breaks at once. Recognisable by the blast radius: dozens of unrelated test classes failing on the same field name in the same deploy. Fix the factory once rather than each test.
5. Explicitly nulling a required field on update
Distinct from the insert case because it only triggers when the field is present in the record and set to null. Common source: an update record built from a partial JSON payload or a field-mapping loop that writes a null for every key it did not find.
// Fails on update — the field is present and explicitly null
update new Contact(Id = c.Id, LastName = null);
// Fine — the field is absent, so the stored value is untouched
update new Contact(Id = c.Id, Email = 'new@example.invalid');6. A before-insert trigger that normally defaults it, bypassed
Perfectly healthy code where the field is populated by a before-insert trigger — until a test disables triggers through a bypass flag or custom setting, or the record is created in a context where the handler short-circuits. The field was never in the factory because the trigger always covered for it. Populate it explicitly in the factory too; relying on automation for a required value makes the data path fragile.
Enumerate them once instead of guessing
Rather than adding fields one failure at a time, ask describe for the full list. Three flags together give the create-required set:
public class RequiredFields {
// Every field that must have a value at insert time.
public static List<String> onCreate(Schema.SObjectType objType) {
List<String> required = new List<String>();
for (Schema.SObjectField f : objType.getDescribe().fields.getMap().values()) {
Schema.DescribeFieldResult d = f.getDescribe();
// isNillable() — false means the database rejects null
// isCreateable() — excludes read-only, formula and system fields
// isDefaultedOnCreate() — excludes fields the platform fills in for you
if (!d.isNillable() && d.isCreateable() && !d.isDefaultedOnCreate()) {
required.add(d.getName());
}
}
return required;
}
}
// Run it against whichever object your factory keeps failing on
System.debug(RequiredFields.onCreate(Contact.SObjectType));
System.debug(RequiredFields.onCreate(InvoiceLine__c.SObjectType));Two caveats. isDefaultedOnCreate() covers platform defaults such as OwnerId and CreatedDate, not a default value you configured on a custom field — those are applied at save time and correctly excluded from the list anyway. And master-detail lookups appear here only if the describe reports them as non-nillable; check d.getRelationshipOrder() != null if you want to identify them explicitly.
The durable fix is a test data factory that builds a valid minimum record per object, so each new required field is a one-line change in one place. See Apex test data factories.
Reproduce and fix it locally — no deploy
Nimbus reads your project's field metadata and master-detail relationships from source and enforces them on insert, so this failure reproduces locally with the same exception type and the missing field named. Inserting a bare Contact against a local project gives:
System.DmlException | REQUIRED_FIELD_MISSING: Required fields are missing: [LastName]The check runs in the same position in the order of execution as the platform's — after before-triggers, before custom validation rules — so a before-insert trigger that defaults the field prevents it locally exactly as it does in the org. Which means the fix-and-recheck loop for a broken factory is a second per attempt:
# Re-run the failing tests
nimbus test "ContactServiceTest.*"
# Or list the required fields for an object directly
nimbus exec scripts/required-fields.apex
# Full account of a failure: exception, file and line, preceding SOQL/DML
nimbus explain ContactServiceTest.testCreateContact