Working with a 2nd-generation managed package and I'm running into issues with, for example, test data.

Example, I need to create a Lead with a record type that exists in my production org, but not in my scratch org.

In my triggers I can use dynamic Apex like:

Id leadRecordTypeId = (Id)lead.get('RecordTypeId'); // Cast to Id

But in writing tests where I need to create a Lead with a certain record type, I'm stuck doing something like this:

private static Lead createLead(Id recordTypeId, String company) {
    Lead testLead = new Lead(
        LastName = 'Test Lead',
        Company = company,
        RecordTypeId = recordTypeId
    return testLead;

If I tried to create a managed package version, it will give me the error:

Field does not exist: RecordTypeId on Lead

I don't want to have to include dummy record types and push those to production just to get this working.

Is there another way?

1 Answer 1


You can detect if there are record types, and if so, then set the field.

static Lead createLead(Id recordTypeId, String company) {
    Lead testLead = new Lead(
        LastName = 'Test Lead',
        Company = company
    if(sobjectType.Lead.fields.getMap().containsKey('RecordTypeId')) {
        testLead.put('RecordTypeId', recordTypeId);
    return testLead;

It's generally a good idea to not have hard-coded references to optional features, like record types or multicurrency, whenever possible.

Alternatively, you can specify unpackagedMetadata in sfdx-project.json, which will be used for the tests, but not include that metadata in the package itself. Note that if you do this, installs can fail if the target organization doesn't have the required settings (e.g. Lead Record Types).

  • +1 - I think on the last para though that the package upload will still fail. unpackagedMetadata is not loaded into the 2GP build org early enough to satisfy compile-time Apex dependencies. objectSettings is, though.
    – David Reed
    Commented Dec 7, 2023 at 17:46
  • Thanks for this, but how would I get a particular record type ID? The following fails when I try to create the package version. Id myRTId = [SELECT Id FROM RecordType WHERE SObjectType = 'Lead' AND DeveloperName = 'Example_Dev_Name' LIMIT 1].Id; And I don't want to pull down a dummy record type to work with. I added a RecordType.json to my "unpackagedMetadata" directory with the same results. Commented Dec 7, 2023 at 18:50
  • @DavidReed Oh. That's unfortunate. The docs aren't clear about that, so I kind of just assumed.
    – sfdcfox
    Commented Dec 7, 2023 at 19:06
  • @user1702965 As David said, looks like the second option isn't viable. You won't be able to find a record type that doesn't exist. That said, I think you might also be using the wrong type package; internal packages should be Unlocked Packages instead.
    – sfdcfox
    Commented Dec 7, 2023 at 19:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .