---
title: "One Lead record type, and the values it never offered"
description: "Builder prospects and homeowner service requests share a single Lead record type, told apart by a Customer Type field. The decision is sound and it is not free: picklist values the field had and the record type never enabled, REQUIRED_FIELD_MISSING on a builder insert, a conversion flow about to turn a builder's office into a job site, and an Opportunity that lands on the wrong record type."
source: "https://noconaconsulting.com/blog/one-lead-record-type-builder-prospects/"
---

# One Lead record type, and the values it never offered

_Build log · Doorvana · Garage door manufacturing & service_

Builder prospects and homeowner service requests share a single Lead record type, told apart by a Customer Type field. The decision is sound and it is not free: picklist values the field had and the record type never enabled, REQUIRED\_FIELD\_MISSING on a builder insert, a conversion flow about to turn a builder's office into a job site, and an Opportunity that lands on the wrong record type.

Nocona Consulting · October 22, 2026 · 8 min read

A new builder prospect is going in. The rep opens the Lead Role dropdown to mark him as the builder’s purchasing agent, and the option is not there. Neither is Project Manager. Neither is Designer. The field has every one of them. The dropdown does not.

Nothing is broken, exactly. It is the first bill for a decision that I still think is right: builder prospects and homeowner service requests share **one Lead record type**. This post is the rest of that bill, line by line, because each line is a thing that one record type quietly makes your job instead of the platform’s.

## The decision

At [Doorvana](https://noconaconsulting.com/work/), new-construction sales starts with outreach to home builders, and the prospecting board for it lives on `Lead`. The handoff note for that build leaned towards a separate `NC_Prospect` Lead record type. The call that came back was the opposite: no second record type. Builder prospects stay on the existing `Service_Lead` record type and are split out by `Customer_Type__c = Builder`.

By the test this org uses for every record type — [can you name the process that differs?](https://noconaconsulting.com/blog/record-types-vs-picklists/) — that is correct. There is one Lead business process, `Service Lead Process`, and builders move through the same statuses as homeowners. The process that really differs is the bid, and that starts after conversion, on the `New_Construction` Opportunity record type. Before conversion, “builder” is something the customer _is_. That is a field.

The record type’s own description now says so, because the label no longer does:

force-app/main/default/objects/Lead/recordTypes/Service\_Lead.recordType-meta.xml

```xml
<RecordType xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>Service_Lead</fullName>
    <active>true</active>
    <businessProcess>Service Lead Process</businessProcess>
    <description>The only Lead record type. Service and replacement requests plus builder
      prospects for new construction; builders are told apart by Customer_Type__c = Builder,
      not a record type.</description>
    <label>Service Lead</label>
    <!-- … -->
</RecordType>
```

“Service Lead” is now a misleading label for a record type that also holds builder prospects. It has not been renamed yet. A label-only change is the safe version; changing the developer name touches every flow, profile and permission set that references it.

## Line one: the values the record type never offered

`Lead_Role__c` is a restricted picklist. Its value set already defined Project Manager, Designer, Builder Representative and Purchasing Agent, for exactly this kind of contact. None of them had ever been enabled on `Service_Lead`.

That is how record types work, and it is easy to forget when an object has only one. A record type carries its own `picklistValues` list for every picklist on the object, and a record of that type is offered those values and no others. Adding a value to the field does not add it to the record type. With one record type the list is invisible, because it never disagrees with anything you can see — until the record type starts serving a kind of record nobody had in mind when its list was last edited.

The fix is four `<values>` entries:

force-app/main/default/objects/Lead/recordTypes/Service\_Lead.recordType-meta.xml

```diff
     <picklistValues>
         <picklist>Lead_Role__c</picklist>
         <values>
             <fullName>Architect</fullName>
             <default>false</default>
         </values>
+        <values>
+            <fullName>Builder Representative</fullName>
+            <default>false</default>
+        </values>
         <values>
             <fullName>Business Contact</fullName>
             <default>false</default>
         </values>
         <values>
             <fullName>Commercial Tenant</fullName>
             <default>false</default>
         </values>
+        <values>
+            <fullName>Designer</fullName>
+            <default>false</default>
+        </values>
         <!-- … Project Manager and Purchasing Agent added the same way … -->
     </picklistValues>
```

One record type is still a record type

With a single record type, every new picklist field and every new value has to be enabled on that record type’s `picklistValues`, or users will not see it. The board’s new restricted picklist, `Last_Outreach_Outcome__c`, went into the same file in the same commit for the same reason. Put the record type file in the same change as the field, every time.

There is a quieter cost in the same file. Picklist defaults are set per record type, so everything sharing a record type shares its defaults. On `Service_Lead`, `Lead_Role__c` defaults to Homeowner. That is right for the service desk, and it is the value a builder prospect starts with too unless something sets it.

## Line two: required means required for everyone

The acceptance script inserts five fabricated builder prospects. The first run did not get as far as the board:

The insert that failed before the test began

_“REQUIRED\_FIELD\_MISSING, Required fields are missing: \[Lead\_Channel\_\_c, Request\_Type\_\_c\]”_

Both fields are `<required>true</required>` in their field definitions. That is a service-intake rule: every homeowner enquiry must say how it arrived and what it is about. Field-level required applies on every path, Apex and flows included, and on every record of every kind. Share the record type and you share the rule.

Neither field is meaningless for a builder, so the answer was to give them honest values, not to relax the rule for the service desk. A builder prospect is `Outbound Call` and `New Construction`:

scripts/apex/prospecting-board-acceptance.apex

```apex
Lead newProspect(String company, String first, String last, String phone) {
    return new Lead(
        FirstName = first, LastName = last, Business_Name__c = company, Company = company,
        Customer_Type__c = 'Builder', Lead_Role__c = 'Builder Representative',
        LeadSource = 'Outbound - Drive By', Phone = phone,
        // Universally required on Lead (a service-intake rule); builder prospects answer it this way.
        Lead_Channel__c = 'Outbound Call', Request_Type__c = 'New Construction'
    );
}
```

`New Construction` being available on `Service_Lead` at all is the result of [an earlier fix](https://noconaconsulting.com/blog/flow-choice-set-record-type-filtering/), when that value was missing from the record type and a new-construction enquiry could not be saved by any route.

## Line three: the office that nearly became a job site

This is the one that would have hurt.

`Lead_Convert_Build_Property_And_Household` is a record-triggered flow on Lead that runs after save when `IsConverted` becomes true. It builds what standard conversion cannot: it creates or matches a `Location` from the lead’s address, links it to the household Account with a stock `AssociatedLocation`, and stamps `Opportunity.Location__c` so the Field Service chain has a property to hang a Work Order on.

For a homeowner, the lead’s address _is_ the property. For a builder, it is the builder’s office. Run unchanged on a builder lead, the flow would have created a property `Location` at the office, linked it to the builder’s Account, and stamped it onto the bid as its job site — the place a crew would eventually be sent to install doors.

Nothing would have errored. The record would have looked complete. The fix is one more condition on the existing decision:

force-app/main/default/flows/Lead\_Convert\_Build\_Property\_And\_Household.flow-meta.xml

```xml
<decisions>
    <description>… A Builder lead's address is the builder's office, not a job site, so
      builder prospects never create a property Location or AssociatedLocation; the job site
      arrives later, on the Opportunity.</description>
    <name>Has_Service_Address</name>
    <!-- … -->
        <conditions>
            <leftValueReference>$Record.Customer_Type__c</leftValueReference>
            <operator>NotEqualTo</operator>
            <rightValue>
                <stringValue>Builder</stringValue>
            </rightValue>
        </conditions>
```

Acceptance case 4 converts a builder and checks the result directly: `Opportunity.Location__c` is null, no new `Location` exists at the office street address, and the builder’s Account has no `AssociatedLocation`.

A second record type would not have saved you here

This flow keys off the address, not the record type. It would have done the same thing to a builder lead on an `NC_Prospect` record type unless someone thought to add the condition. Any automation written when every lead was a homeowner carries that assumption, whichever way you split the object. Audit it either way.

## Line four: the Opportunity lands on the wrong record type

Lead conversion creates the Opportunity with the **converting user’s default Opportunity record type**. Lead conversion field mapping — `LeadConvertSettings` — maps field values; it does not pick the record type. For a rep whose default is Service, a converted builder produces a Service Opportunity on the transactional process, which is the wrong pipeline, the wrong stages and the wrong forecast.

The same after-save flow now checks for a converted builder first, then moves the Opportunity:

force-app/main/default/flows/Lead\_Convert\_Build\_Property\_And\_Household.flow-meta.xml

```xml
<rules>
    <name>Builder_With_Opportunity</name>
    <conditionLogic>and</conditionLogic>
    <conditions>
        <leftValueReference>$Record.Customer_Type__c</leftValueReference>
        <operator>EqualTo</operator>
        <rightValue><stringValue>Builder</stringValue></rightValue>
    </conditions>
    <conditions>
        <leftValueReference>$Record.ConvertedOpportunityId</leftValueReference>
        <operator>IsNull</operator>
        <rightValue><booleanValue>false</booleanValue></rightValue>
    </conditions>
    <connector><targetReference>Get_New_Construction_Record_Type</targetReference></connector>
    <label>Yes</label>
</rules>
```

It looks up the `New_Construction` record type by `DeveloperName`, never by a hard-coded ID, and sets `RecordTypeId` on the converted Opportunity. Changing the record type is not enough by itself, because the stage came from the old process. A formula keeps a stage that already belongs to the Bid process and turns anything else into Discovery:

force-app/main/default/flows/Lead\_Convert\_Build\_Property\_And\_Household.flow-meta.xml

```xml
<formulas>
    <description>Keeps a stage that already belongs to the Bid process; anything else
      (a Transactional stage from the default record type) becomes Discovery.</description>
    <name>Bid_Stage</name>
    <dataType>String</dataType>
    <expression>IF(OR(TEXT({!Get_Converted_Opportunity.StageName}) = "Discovery",
      TEXT({!Get_Converted_Opportunity.StageName}) = "Working - Bid",
      TEXT({!Get_Converted_Opportunity.StageName}) = "Delivered - Bid",
      TEXT({!Get_Converted_Opportunity.StageName}) = "Closed Won",
      TEXT({!Get_Converted_Opportunity.StageName}) = "Closed Lost"),
      TEXT({!Get_Converted_Opportunity.StageName}), "Discovery")</expression>
</formulas>
```

Case 4 asserts both: `RecordType.DeveloperName = 'New_Construction'` and a Bid stage.

## What one record type moved, and where to

| What a second record type would have done | Where it lives with one record type |
| --- | --- |
| Its own picklist value list | Every value enabled on `Service_Lead`’s `picklistValues` |
| Its own layout | A Dynamic Forms field section with a component visibility rule on `Customer_Type__c` |
| Its own picklist defaults | Shared defaults, set by automation where they do not fit |
| An obvious branch in automation | An explicit `Customer_Type__c` condition in every flow that cares |
| Required fields scoped to it | Required for everyone, answered honestly per kind |

The Lightning record page’s “Prospecting” section is the second row in practice:

force-app/main/default/flexipages/Lead\_Record\_Page\_Service\_lead.flexipage-meta.xml

```xml
<componentName>flexipage:fieldSection</componentName>
<identifier>flexipage_fieldSection_prospecting</identifier>
<visibilityRule>
    <criteria>
        <leftValue>{!Record.Customer_Type__c}</leftValue>
        <operator>EQUAL</operator>
        <rightValue>Builder</rightValue>
    </criteria>
</visibilityRule>
```

None of that is an argument for the second record type. A second record type would have added a `recordTypeVisibilities` entry to every profile and permission set, a record type to choose or derive on every new lead, and a way for a builder to be filed under the wrong one. It would also have left lines one, three and four exactly where they were. The automation audit is needed either way, and the picklist list just moves to a different file.

What one record type does is take the differences out of the place the platform enforces them and put them in fields and flows, where only your tests enforce them. That is a good trade when the process really is the same. Make it knowing the tests are now the enforcement. The acceptance run for the board is 35 checks across five fabricated cases, and case 4 — convert a builder, then read back the Opportunity’s record type, its stage, its `Location__c` and the Account’s `AssociatedLocation` count — is what keeps lines three and four paid.

-   Record types
-   Picklists
-   Lead conversion
-   Flow
-   Dynamic Forms
-   Field Service

Disclosure: Doorvana's owner is also a co-owner of Nocona Consulting. This is a real engagement between two separate companies, but not an arm's-length one — and not an independent reference. [More on the work page](https://noconaconsulting.com/work/).

## FAQ

### Why is a picklist value missing from a Salesforce record even though the field has it?

Because the record's record type does not make that value available. A record type carries its own picklistValues list for every picklist on the object, and only those values are offered on records of that type. Adding a value to the field, or to its global value set, does not add it to existing record types. Check the RecordType metadata for a picklistValues entry for that field and enable the value there.

### Should builder leads and homeowner leads have separate Lead record types?

Only if the Lead process differs: different Lead statuses, a different business process, or genuinely different handling before conversion. If both kinds of lead are worked through the same statuses and the real difference starts after conversion, one Lead record type plus a field such as Customer Type is simpler. The difference then belongs on the Opportunity, where a separate record type can drive a different set of stages.

### Which record type does lead conversion give the new Opportunity?

Standard lead conversion creates the Opportunity with the converting user's default Opportunity record type. Lead conversion field mapping copies field values; it does not set the record type. If certain leads must convert into a particular Opportunity record type, something has to change it afterwards, for example a record-triggered flow on Lead that runs when IsConverted becomes true and updates ConvertedOpportunityId.

### What does REQUIRED_FIELD_MISSING mean when inserting a Lead from Apex or a flow?

A field marked required in its field definition was left blank on the insert. Field-level required applies on every path, including Apex, flows and the API, not only on the page layout. When one Lead record type serves several kinds of lead, a field that is required for one kind is required for all of them, so every intake path has to supply a sensible value.

### If a picklist value is enabled on a record type, can it have a different default for different kinds of record?

No. The default is set once per record type, per picklist. When two kinds of record share a record type they share its picklist defaults as well. A default that only suits one kind has to be removed, or set by automation that checks a field such as Customer Type.
