Record types don't just change a page layout. They define which picklist values are legal for a given record, which business process it follows, and which fields actually matter to the people who use that record every day. Salesforce record type test data that ignores these rules will insert cleanly through almost any API and still be wrong, because the platform's write path rarely enforces record-type-to-picklist logic at the database level. The mismatch shows up later, in reports, in flows, and in validation rules that assume a value set someone forgot to check.
Most test data generators treat picklist fields as flat lists. Pick any value from the full set, write it, move on. That works fine for a demo org with one record type per object. It falls apart the moment an org has three Opportunity record types, each tied to a different sales process with a different Stage picklist, or a Case object where Record Type A only shows statuses relevant to field service and Record Type B is scoped to billing disputes.
What Record Types Actually Control (And Why Generators Miss It)
A record type in Salesforce is a pointer. It points to a page layout, a set of picklist values for each picklist field on the object, and in some cases a business process like a sales process or support process. None of that is stored as a simple field-level constraint the way a required field or a length limit is. It lives in metadata relationships: RecordType, RecordTypePicklistValue, and the business process objects that sit underneath Opportunity, Lead, and Case.
This is why a generic random-value approach fails quietly. The Stage field on Opportunity is a single picklist at the object level, but each record type can expose a different subset of those values through its assigned sales process. Insert a record with Record Type set to Renewal and Stage set to a value only valid for the New Business process, and Salesforce will often accept it. The field exists. The value exists. The combination just doesn't make sense to anyone looking at a pipeline report by record type.
The Hidden Failure: Valid Insert, Invalid Business Data
I've seen QA teams spend a full sprint chasing a flow bug that turned out to be bad test data, not bad logic. The flow fired correctly. It just received a Case with Record Type Field_Service and a Status of Escalated to Billing, a value that should never appear on that record type in production. The flow had no branch for that case because no sane user could create it through the UI. The automation broke, and the team blamed the trigger.
That's the real cost of ignoring record types in test data generation. It's not a rejected API call you can catch in a log. It's a silent, structurally invalid record that passes every schema check and then produces behavior nobody designed for. Validation rules that reference record type conditionally (a common pattern, something like RecordType.DeveloperName equals Renewal, require a Close Reason) will catch some of these mismatches, but plenty of orgs don't have validation rules tight enough to cover every picklist-to-record-type pairing. The gap gets filled by test data that looks plausible and isn't.
How Picklist Value Sets Map to Record Types in the Schema
The mapping lives in the Metadata API and Tooling API, not in the standard describe call most people reach for first. A plain describeSObjectResult gives you every possible picklist value for a field across the whole object, with no indication of which record type each value belongs to. To get the real mapping, you need the RecordTypeInfo data per picklist field, which Salesforce exposes through the UI API or by querying RecordType and its associated picklist value metadata directly.
Here's a simplified view of what that mapping looks like for an Opportunity object with two record types:
| Record Type | Business Process | Valid Stage Values |
|---|---|---|
| New Business | Standard Sales Process | Prospecting, Qualification, Proposal, Negotiation, Closed Won, Closed Lost |
| Renewal | Renewal Process | Renewal Initiated, Renewal Negotiation, Renewed, Churned |
Generate data by randomly selecting from the full Stage picklist, and you'll eventually assign Negotiation to a Renewal record. It's a value that genuinely exists on the object. It's also one that no Renewal-process report will ever expect to see, which means your test coverage for renewal dashboards and forecast rollups is built on fiction.
Page Layouts, Required Fields, and the Record Type Trap
Picklists are the obvious failure point, but required fields follow the same pattern and get missed just as often. Page layout assignment is per record type, and a field can be required on one layout while optional or hidden on another. A Case layout for the Billing record type might require a Dispute Amount field. The Field Service layout on the same object might not show that field at all, but still require Asset.
Standard object describes report a field as required only when it's marked required at the field-definition level, which is org-wide. Layout-level requiredness, enforced through the page layout rather than the field metadata, won't show up there. Test data generated purely from the object describe will satisfy field-level requirements and still produce records that would be rejected or flagged in the actual UI a user works in. This matters most for UAT and layout-dependent flow testing, where the point is to simulate what a real user does, not just what the API accepts.
Building Record-Type-Aware Test Data With Bulk API v2
Bulk API v2 doesn't care about any of this on its own. It will load whatever rows you hand it, as fast as you hand them, with no awareness of record type picklist scoping. That's exactly why the generation step matters more than the load step. The job is to build the CSV or JSON payload so that every row already respects the record type it's assigned to, before it ever reaches the Bulk API endpoint.
SproutEzee handles this by reading the org's record type and picklist value metadata as part of its schema scan, then scoping value selection per record type during generation. If a job is set to produce 10,000 Opportunity records split across three record types, each record gets its Stage, Type, and Lead Source values drawn from the subset valid for its own record type, not from the global picklist. The same scoping applies to any picklist field with record-type-specific value sets, not just the fields tied to formal business processes.
This also solves a related problem: business process stage ordering. A Renewal process might not include a Qualification-equivalent stage at all. Random selection can still produce a technically valid value while skipping the stage progression a flow or process builder expects to see over time. Record-type-aware generation respects not just which values are legal, but keeps the relative ordering sane when you're generating historical-looking data across a date range.
A Practical Checklist Before You Load
Before running a large test data load against an org with multiple record types, it's worth working through a short list rather than trusting the generator by default.
- Pull RecordTypePicklistValue mappings for every picklist field that varies by record type, not just the obvious ones like Stage and Status.
- Check page layout assignments per record type for required fields that aren't required at the field-definition level.
- Confirm business process assignments on Opportunity, Lead, and Case so stage or status progression matches what each record type expects.
- Test validation rules that reference RecordType.DeveloperName directly, since these are the most likely place a mismatch gets caught, or missed.
- Sample a handful of generated records manually and open them in the UI with the correct record type selected. If a value looks wrong on screen, it was wrong in the generator too.
None of this is complicated once it's on a checklist. The reason it gets skipped is that record type scoping isn't visible in a standard object describe, so teams building their own scripts simply don't know it's there until a bug report points it back at the data. A generator that reads the full metadata picture up front avoids that entire class of defect, and that's worth more than almost any volume or speed claim a tool can make.
Frequently Asked Questions
What is a Salesforce record type and why does it matter for test data?
A record type controls which page layout a record uses, which picklist values are available for certain fields, and in some cases which business process the record follows. Test data that ignores record type context can assign picklist values that exist on the object but are invalid for that specific record type. This produces records that look fine in a database query but would never occur through normal user activity.
Will Bulk API v2 reject an invalid picklist-to-record-type combination?
Usually not. Bulk API v2 validates against field-level metadata, such as whether a value exists anywhere on the picklist and whether a field marked required at the object level has a value. It does not enforce record-type-specific picklist value sets unless a validation rule explicitly checks RecordType.DeveloperName, so most invalid combinations load successfully and fail silently later.
How do I find which picklist values are valid for a specific record type?
The mapping is available through the Metadata API or Tooling API, specifically through RecordType and its associated picklist value metadata, or via the UI API which returns RecordTypeInfo scoped per field. A plain describeSObjectResult call will not show this, since it returns the full picklist value set for the object regardless of record type.
Does SproutEzee generate test data that respects record type picklist values?
Yes. SproutEzee reads record type and picklist value mappings during its schema scan and scopes generated values to the correct record type for each row. This applies to Opportunity Stage, Lead Status, Case Status, and any other picklist field with record-type-specific value sets, keeping generated data aligned with what a real user would actually be able to select.
What happens downstream if test data ignores record type picklist rules?
Flows, validation rules, and reports that assume record-type-specific picklist logic can behave unpredictably when fed records that violate that logic. Teams often misdiagnose the resulting issue as an automation bug rather than a data problem, since the record loaded without error. The fix usually requires regenerating the affected test data rather than touching the automation at all.