Skip to main content
SFDC Developers
DevOps

2GP Conversion Error: Fixing Platform Event Subscriber Config

Vinay Vernekar · · 8 min read

The shift from Salesforce's Metadata API (1GP) to the Source Format (2GP) using SFDX offers significant benefits for modern development lifecycles, CI/CD pipelines, and source control integration. However, transitioning complex dependencies often surfaces opaque errors. One particularly stubborn issue developers face during the conversion from an older source format or when refreshing a scratch org metadata pull is the dreaded Platform Event Subscriber Configuration error.

This error typically appears when SFDX cannot correctly resolve the metadata dependency linking a Platform Event (PE) to its consuming entity—often an Apex Trigger, an External Service configuration, or most commonly, a specific Apex Class or Handler that subscribes to the event.

In this comprehensive tutorial, we will dissect why this error occurs, examine the required metadata structure, and provide practical steps using sfdx force:source:convert and best practices to ensure your Platform Event subscriptions are correctly represented in your 2GP source structure.

Understanding the Platform Event Subscriber Context

In Salesforce, Platform Events are asynchronous messaging services. For an Apex class or a Flow to process an event, it must explicitly declare its intent to subscribe. When you deploy metadata directly via the Metadata API (1GP), Salesforce implicitly handles some dependency resolution behind the scenes, especially if the subscriber class is defined in the same package or deployment scope.

In the 2GP world, everything must be explicitly defined in metadata files. The subscription mechanism for Apex classes is stored in a specific metadata type: PlatformEventSubscriberConfig. This configuration tells the platform which Apex class (Subscriber.ApexClassName) should handle events published to a specific channel (EventBusConfig.TopicName).

When you pull metadata using sfdx force:source:pull from an org that uses Platform Events heavily, or when you are converting an older project, Salesforce might successfully pull the CustomObject definition for the Platform Event itself, and the ApexClass definition, but it often fails to generate or correctly link the necessary PlatformEventSubscriberConfig metadata file for 2GP conversion.

Why Conversion Fails

The conversion process (sfdx force:source:convert) translates the XML structure used by the Metadata API into the standardized folder and file structure required for 2GP Git repository storage. If a consumer (like an Apex handler) is relying on a specific PE subscription that isn't explicitly defined in a resolvable metadata component recognized by the converter, the tool throws the error because it cannot locate the source configuration artifact it expects to map.

Specifically, the error usually manifests during the conversion phase because the converter cannot find the necessary definition tying the handler to the topic, leading to ambiguity regarding how the consuming class should be treated in the source structure.

Diagnosing Missing PlatformEventSubscriberConfig Metadata

The first step in resolution is confirming where the subscription is defined in the source organization and ensuring the required metadata types are present.

If you are pulling metadata from an org where these events are already set up, you must pull the specific metadata component that captures the subscription relationship. The standard component name for this relationship is often not intuitive.

1. Identifying the Apex Subscriber

Ensure you know which Apex class is subscribing to the event. A typical subscription looks like this in Apex:

@isTest(SeeAllData=false)
public class MyPlatformEventHandler implements EventHandlerInterface {
    @InvocableMethod
    public void handleEvents(List<MyCustomEvent__e> events) {
        // Business logic to process the incoming event
        System.debug('Received event: ' + events.size());
    }
}

If the subscription is handled via an Apex class method annotated with @InvocableMethod (common in Flow/Event Relay scenarios) or a class implementing the EventBus.MessageContext interface for asynchronous processing, the dependency must be captured.

2. Using sfdx force:source:retrieve with Specific Types

When pulling metadata into your scratch org or development sandbox to prepare for conversion, explicitly request the required metadata types. If you suspect the configuration is missing, try retrieving it directly.

Use the sfdx force:source:retrieve command, specifying the Apex class name and the configuration type:

# Retrieve the Apex Class definition
sfdx force:source:retrieve -m ApexClass:MyPlatformEventHandler

# Crucially, try retrieving the specific configuration type
sfdx force:source:retrieve -m PlatformEventSubscriberConfig

If the system successfully retrieves a component for PlatformEventSubscriberConfig, look in your local source directory (under force-app/main/default/platformEventSubscriberConfigs/). You should see an XML file that defines the link, often named after the Apex class or the event topic.

For example, a successfully retrieved configuration might look like this in XML:

<?xml version="1.0" encoding="UTF-8"?>
<PlatformEventSubscriberConfig xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>59.0</apiVersion>
    <eventBusConfig>
        <topicName>MyCustomEvent__e</topicName>
    </eventBusConfig>
    <handlerInfo>
        <apexClassName>MyPlatformEventHandler</apexClassName>
        <type>PlatformEvent</type>
    </handlerInfo>
    <isActive>true</isActive>
    <masterLabel>MyCustomEventSubscriptionConfig</masterLabel>
</PlatformEventSubscriberConfig>

If retrieving this type yields no results, it means the subscription was likely established through a declarative tool (like the Event Monitoring setup UI or sometimes Flow actions) that does not always translate cleanly into the PlatformEventSubscriberConfig XML during initial source tracking synchronization. This is the root cause of the 2GP conversion failure.

Fixing the Configuration During Conversion

If standard retrieval fails to yield the configuration file needed for 2GP conversion, we must manually ensure this metadata exists either in the source org before conversion or inject it into the 2GP structure after conversion but before the final deployment.

Method 1: Declaratively Recreating the Subscription (Recommended)

If you are working from a sandbox or production org, the safest approach is to re-establish the subscription declaratively, ensuring the metadata artifact is generated, and then pull the source.

  1. Navigate to Setup: Go to Platform Events setup.
  2. Find Your Event: Locate the specific Platform Event definition (e.g., MyCustomEvent__e).
  3. Check Subscriptions: Look for the 'Subscribers' or 'Event Triggers' section.
  4. Remove and Re-add (If necessary): If you see the Apex class listed as a subscriber, sometimes simply deactivating and reactivating the subscription link (if possible) forces metadata regeneration. If the link is missing, add your Apex handler class (MyPlatformEventHandler) as a new subscriber to the event topic.
  5. Retrieve Again: Once re-established, run sfdx force:source:pull again. The PlatformEventSubscriberConfig file should now appear in your local source tree.
  6. Convert: Proceed with sfdx force:source:convert.

Method 2: Manual Injection into 2GP Source (Advanced)

If you cannot easily modify the source org (e.g., deploying between two sandboxes where you only control the target structure), you can manually create the required metadata file structure in your local 2GP source directory.

Assuming your event is named MyCustomEvent__e and your handler is MyPlatformEventHandler:

  1. Create Directory: Ensure the directory structure exists within your package structure (e.g., force-app/main/default/platformEventSubscriberConfigs/).
  2. Create File: Create a file inside that directory. The filename must correspond to a unique label, often following the pattern <ApexClassName>-<TopicName>. Let's name it MyPlatformEventHandler-MyCustomEvent.config-meta.xml.
  3. Populate XML: Insert the required structure (adapted from the example above):
<?xml version="1.0" encoding="UTF-8"?>
<PlatformEventSubscriberConfig xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>59.0</apiVersion>
    <eventBusConfig>
        <topicName>MyCustomEvent__e</topicName>
    </eventBusConfig>
    <handlerInfo>
        <apexClassName>MyPlatformEventHandler</apexClassName>
        <type>PlatformEvent</type>
    </handlerInfo>
    <isActive>true</isActive>
    <masterLabel>MyPlatformEventHandlerMyCustomEvent</masterLabel>
</PlatformEventSubscriberConfig>

Important Note on Dependencies: When manually injecting, you must ensure that the ApexClass metadata for MyPlatformEventHandler is also present in your 2GP source structure (under classes/) and that the API version aligns across all files.

  1. Convert: Now, when you run sfdx force:source:convert, the converter will see the explicit PlatformEventSubscriberConfig definition, recognize its dependency on the existing ApexClass, and successfully translate the structure into the 2GP format.

Handling External Service Subscriptions

If your subscription to the Platform Event is not handled by Apex but through an External Service (often used when configuring event-driven connectivity via External Service Registration), the dependency metadata is slightly different, although the conversion error might still surface under the same umbrella if dependencies are mismanaged.

External Service configurations tied to events are usually managed under the ExternalServiceRegistration metadata type. If you are using External Services, ensure that the related Service and its associated definitions (including connection details and flow linkage, if applicable) are fully present in the source structure before conversion. Unlike Apex subscriptions, External Services generally rely on the primary registration metadata being pulled correctly, and the platform infers the subscriber link.

If you are using Flow to handle the event (using the Event-Triggered Flow targeting the PE), the Flow itself is the subscriber. In this case, the Flow definition (Flow/My_Event_Triggered_Flow.flow-meta.xml) must be present. The Flow definition implicitly defines the subscription channel, and the 2GP conversion process generally handles the dependency on the PE correctly if the Flow is present.

Key Takeaways

The 'Platform Event Subscriber Configuration' error during 2GP source conversion is fundamentally a dependency resolution failure where the link between an event topic and its consumer is not explicitly declared in a recognized metadata artifact.

  • Identify the Consumer: Determine if the consumer is an Apex class, an External Service, or a Flow.
  • Target PlatformEventSubscriberConfig: For Apex consumers, this specific metadata type is the crucial missing piece causing conversion errors.
  • Force Retrieval: Use sfdx force:source:retrieve -m PlatformEventSubscriberConfig against the source org to attempt to pull the required definition.
  • Recreate Declaratively: If retrieval fails, re-establishing the subscription link declaratively in the source org forces the platform to generate the necessary XML artifact.
  • Manual Injection: For advanced scenarios, manually creating the PlatformEventSubscriberConfig XML file in the correct 2GP directory structure, referencing the existing Apex class, can bypass the conversion blocker.

Share this article

Vinay Vernekar

Vinay Vernekar

Salesforce Developer & Founder

Vinay is a seasoned Salesforce developer with over a decade of experience building enterprise solutions on the Salesforce platform. He founded SFDCDevelopers.com to share practical tutorials, best practices, and career guidance with the global Salesforce community.

Comments

Loading comments...

Leave a Comment

Trending Now
Check back soon for trending Salesforce developer content