Looking for some advice on troubleshooting this pagination logic issue when fetching all queues across multiple divisions using the Platform SDK for JavaScript. I am attempting to build a utility function that aggregates queue metadata for a cross-divisional reporting tool. The current implementation iterates through a list of division IDs and calls routingClient.getRoutingQueues for each. However, the SDK’s built-in pagination helper seems to reset or conflict when chained across multiple asynchronous calls, resulting in incomplete data sets for divisions with more than 100 queues. I am not seeing any explicit 429 or 500 errors, but the final array length is consistently short. Here is the core loop:
Is there a recommended pattern for handling cross-division pagination with the JS SDK, or should I be falling back to raw REST calls with manual cursor management to ensure completeness?
async def fetch_all_queues(divisions: list[str]) -> list[Queue]:
queues = []
for div_id in divisions:
async for page in client.routing_api.get_routing_queues(division_id=div_id, expand=['members']):
queues.extend(page.entities)
return queues
I usually solve this by iterating divisions explicitly. The JS SDK helper handles per-call pagination well. Do not mix division contexts in one iterator. Collect results in a flat list. This avoids state desynchronization errors.
This is actually a known issue… The JS SDK paginator state gets corrupted when you switch division contexts mid-stream. Just use the Python SDK for this bulk job and handle the division loop outside the iterator.
from genesyscloud import PlatformClient, RoutingApi
client = PlatformClient("https://api.mypurecloud.com")
client.login_client_credentials("client_id", "client_secret")
routing = client.get_routing_api()
all_queues = []
for div in divisions:
for page in routing.get_routing_queues(division_id=div, expand=['members']):
all_queues.extend(page.entities)
If I remember right, the JS SDK pagination helper maintains internal state that binds to a specific API call context, which causes it to break when you switch division IDs mid-stream. The suggestion above to iterate explicitly is the correct path, but you need to ensure you are not relying on the asyncIterator pattern across different division calls. Instead, you should wrap each division’s fetch in its own promise and handle the pagination cursor manually within that scope. This prevents the SDK from trying to merge cursors from different division endpoints, which leads to the 400 or 404 errors you are seeing.
Here is how I structure this in my CLI tools using the PureCloudPlatformClientV2. We use Promise.all to fetch divisions in parallel, but inside that, we use a simple recursive or while-loop pattern to handle pagination for each division independently. This keeps the state clean.
This approach avoids the SDK paginator’s internal state corruption entirely. By managing the sequenceId manually within each division’s loop, you ensure that the pagination context never crosses division boundaries. It is a bit more verbose than using the built-in iterator, but it is significantly more stable for bulk operations across multiple divisions. Make sure you also check for rate limits if you are hitting many divisions at once, as parallel requests can trigger 429s quickly.
The explicit loop approach resolves the state corruption. I implemented the manual cursor handling within a dedicated service method. This isolates the pagination context per division, preventing the SDK helper from carrying over stale next-page links.
async fetchQueues(divisions: string[]): Promise<Queue[]> {
const queues: Queue[] = [];
for (const div of divisions) {
let nextId: string | undefined;
do {
const resp = await this.platformClient.RoutingApi.getRoutingQueues(div, undefined, undefined, undefined, nextId);
queues.push(...resp.entities);
nextId = resp.nextPageCursor;
} while (nextId);
}
return queues;
}
This pattern ensures thread safety in Angular services. The do-while loop consumes each division’s results completely before switching contexts. It avoids the race conditions observed with the default async iterator when switching divisionId parameters dynamically.