ENGLISH

Salesforce API pagination in JDE Orchestrator: why recursion wasn’t the fix (it wouldn’t even let me save it)

By mariogarcia August 28, 2026 · 3 min read EN

The symptom: missing customers

The project was syncing customers from Salesforce into JD Edwards every night. The first version worked… partially. Sales started reporting customers that existed in Salesforce but weren’t showing up in JDE. Not all of them, just some, with no obvious pattern. That kind of intermittent failure is the worst to chase, because your first instinct is to doubt the data, not the integration. Illustration of a data stream split into blocks being processed one by one until the full set is complete

Root cause #1: Salesforce’s own pagination

Salesforce’s REST API doesn’t return everything in one shot. It hands you a first batch of records and a pointer (nextRecordsUrl) to fetch the next one. My first Custom Request only ever read that first batch and reported the call as complete. If the batch of new customers happened to be small, it fit inside a single page by coincidence and everything looked fine. If it was large, everything past the first page silently disappeared -with the orchestration reporting a full success, because as far as it knew, the call had gone perfectly.

The attempted fix: a recursive orchestration

The obvious answer was to have the orchestration call itself as long as Salesforce kept returning a nextRecordsUrl. I built it, tested it in the designer, it worked. The problem showed up when I tried to share it as a UDO.

Root cause #2: the loop that wouldn’t let me save it

Adding the object’s dependencies so it could be shared, the orchestration ended up referencing itself as part of its own dependency tree. The dependency-resolution process hit an infinite loop -not at runtime, but while trying to save and share the object. The screen just hung, calculating dependencies that never finished resolving. I couldn’t share an orchestration that worked flawlessly in testing. The real problem was no longer pagination: it was that Orchestrator can’t handle an orchestration referencing itself inside its own dependency list.

The actual fix: a Groovy-built array plus Rule iteration

I dropped recursion entirely. Instead:

  • First call gets the number of clients to get.
  • A Custom Java script in Groovy, reads the total record count and page size
  • That calculation is delivered as a plain array.
  • A Rule with native iteration walks that array and makes each API call in turn, accumulating the results.

No recursion means no self-reference, and no self-reference means no dependency loop to resolve. The orchestration saves and shares without issue, and as a bonus, the number of calls is fixed and calculated before the first real request even goes out.

The business impact

Before this, someone in sales manually cross-checked Salesforce against JDE two or three times a week to catch missing customers -roughly 3-4 hours a week, and cases still slipped through until an order failed because the customer didn’t exist. Now the sync runs every night, pulls one hundred percent of new or updated customers, and nobody has to cross-reference lists by hand.

The lesson

When something breaks in Orchestrator, separate two questions that feel like one: does it fail at runtime, or does it fail when you try to save or share it? Those are two completely different classes of error, and mixing them up will have you chasing the wrong cause for days.

NEXT ISSUE · TUESDAY

One email a week. Only when I actually have something to say.

No recycled content. No ads. Unsubscribe with one click.

Leave a Comment