Skip to content

Salesforce 'New Object' trigger: Inconsistent event format between deploy-time and real-time events #18929

@shadyshoha

Description

@shadyshoha

Description

The Salesforce "New Object" trigger (e.g., for Leads) emits events with inconsistent formats between:

  1. Historical events emitted during initial deployment (deploy() hook)
  2. Real-time events received via webhooks after deployment

This causes downstream workflows to fail or behave unexpectedly when they expect a consistent data structure.

Steps to Reproduce

  1. Create a workflow using the Salesforce "New Record (Instant)" trigger for the Lead object
  2. Deploy the trigger
  3. Observe the format of historical events emitted immediately after deployment
  4. Create a new Lead in Salesforce
  5. Observe the format of the real-time webhook event
  6. Compare the two formats

Expected Behavior

All events (both historical and real-time) should have the same consistent structure.

Actual Behavior

Historical Event Format (during deploy)

{
  "body": {
    "New": {
      "attributes": {
        "type": "Lead",
        "url": "/services/data/v50.0/sobjects/Lead/00Q123456789ABC"
      },
      "Id": "00Q123456789ABC",
      "LastName": "Doe",
      "FirstName": "Jane",
      "Company": "Example Corp",
      "Status": "New",
      "Email": "jane.doe@example.com",
      "Phone": "555-0100",
      "CreatedDate": "2025-11-01T12:00:00.000+0000",
      "LastModifiedDate": "2025-11-01T12:00:00.000+0000"
    },
    "UserId": "00Q123456789ABC"
  }
}

Real-time Webhook Event Format

{
  "body": {
    "Id": "00Q123456789ABC",
    "attributes": {
      "type": "Lead",
      "url": "/services/data/v50.0/sobjects/Lead/00Q123456789ABC"
    },
    "LastName": "Doe",
    "FirstName": "Jane",
    "Company": "Example Corp",
    "Status": "New",
    "Email": "jane.doe@example.com",
    "Phone": "555-0100",
    "CreatedDate": "2025-11-01T12:00:00.000+0000",
    "LastModifiedDate": "2025-11-01T12:00:00.000+0000"
  }
}

Notice that historical events wrap the Salesforce object data inside a "New" property, while real-time webhook events place the data directly in the body.

Root Cause Analysis

The issue is in the deploy() hook of common-new-record.mjs:

File: components/salesforce_rest_api/sources/common/common-new-record.mjs (lines 19-26)

async deploy() {
  // ... fetch recent items
  for (const id of ids.slice(-25)) {
    const object = await this.salesforce.getSObject(objectType, id);
    const event = {
      body: {
        "New": object,      // ← Manually wraps data in "New" property
        "UserId": id,
      },
    };
    this.processWebhookEvent(event);
  }
}

The deploy hook manually wraps the Salesforce object data in a "New" property to match what the generateWebhookMeta() method expects (line 83):

generateWebhookMeta(data) {
  const nameField = this.getNameField();
  const { New: newObject } = data.body;  // ← Expects "New" property to exist
  // ...
}

However, the actual webhook events from the salesforce-webhooks npm package arrive with the data directly in the body without the "New" wrapper, causing the inconsistency.

Proposed Solutions

Option 1: Remove "New" wrapper from deploy hook (Recommended)

Modify the deploy hook to emit events in the same format as real webhooks:

const event = {
  body: object,  // No "New" wrapper
};

And update generateWebhookMeta() to read directly from data.body:

generateWebhookMeta(data) {
  const nameField = this.getNameField();
  const {
    CreatedDate: createdDate,
    Id: id,
    [nameField]: name,
  } = data.body;  // Read directly from body
  // ...
}

Option 2: Normalize webhook events

Add a wrapper to incoming webhook events to match the deploy format (though this seems less ideal).

Option 3: Support both formats

Make the event processing logic flexible enough to handle both formats (adds complexity).

Impact

  • Users building workflows that access event.body.New.* will work during testing (with historical events) but fail when real events arrive
  • Users accessing event.body.* directly will experience the opposite problem
  • This creates confusion and unreliable workflows

Environment

  • Component: salesforce_rest_api
  • Affected files:
    • components/salesforce_rest_api/sources/common/common-new-record.mjs
    • components/salesforce_rest_api/sources/common/common-webhook-methods.mjs
  • Trigger: "New Record (Instant, of Selectable Type)" and all similar triggers

Additional Context

This issue likely affects other similar triggers that use the same pattern (e.g., new Case, new Opportunity, etc.) since they all inherit from common-new-record.mjs.

Metadata

Metadata

Assignees

Labels

triagedFor maintainers: This issue has been triaged by a Pipedream employee

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions