Skip to content

fix(hubspot): listContacts omits null after so it can paginate past page 1#93

Merged
d-klotz merged 1 commit into
nextfrom
fix/hubspot-listcontacts-pagination
Jun 8, 2026
Merged

fix(hubspot): listContacts omits null after so it can paginate past page 1#93
d-klotz merged 1 commit into
nextfrom
fix/hubspot-listcontacts-pagination

Conversation

@d-klotz

@d-klotz d-klotz commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Problem

Api.listContacts always places after in the query string, defaulting it to null when no cursor is supplied:

const after = get(params, 'after', null);
// ...
query: { limit, after, properties }

HubSpot's GET /crm/v3/objects/contacts rejects after=null (and after=) with a 400, so a caller can never page past the first page. The practical fallout: integrations are forced onto the search endpoint for full enumeration, which HubSpot hard-caps at 10,000 results — so any portal with >10k contacts cannot be fully listed. (We hit exactly this: a 100k-contact initial sync died at fetched=10000.)

Fix

Only include after in the query once a cursor is actually present (i.e. from the second page onward). First-page calls now send just limit + properties; subsequent pages send the paging.next.after cursor.

const query = { limit, properties };
if (after !== null && after !== undefined && after !== '') {
    query.after = after;
}

Tests

New tests/listContacts.test.js (fast unit tests stubbing _get, since the existing api.test.js is live-OAuth):

  • first page (no cursor) → query has no after
  • subsequent page → after is sent
  • after: null → treated as "no cursor"

🤖 Generated with Claude Code

Version

Published prerelease version: @friggframework/api-module-hubspot@2.0.0-next.6

Changelog

🚀 Enhancement

  • @friggframework/api-module-microsoft-teams, @friggframework/api-module-slack, @friggframework/api-module-42matters, @friggframework/api-module-asana, @friggframework/api-module-attio, @friggframework/api-module-clio, @friggframework/api-module-connectwise, @friggframework/api-module-contentful, @friggframework/api-module-contentstack, @friggframework/api-module-crossbeam, @friggframework/api-module-deel, @friggframework/api-module-frigg-scale-test, @friggframework/api-module-frontify, @friggframework/api-module-google-calendar, @friggframework/api-module-google-drive, @friggframework/api-module-helpscout, @friggframework/api-module-hubspot, @friggframework/api-module-ironclad, @friggframework/api-module-linear, @friggframework/api-module-pipedrive, @friggframework/api-module-salesforce, @friggframework/api-module-stripe, @friggframework/api-module-unbabel-projects, @friggframework/api-module-unbabel, @friggframework/api-module-zoho-crm, @friggframework/api-module-zoom
    • feat(hubspot): DB-free webhook receiver via 2-hop resolve #92 (@d-klotz)
  • @friggframework/api-module-microsoft-teams, @friggframework/api-module-slack, @friggframework/api-module-42matters, @friggframework/api-module-asana, @friggframework/api-module-attio, @friggframework/api-module-connectwise, @friggframework/api-module-contentful, @friggframework/api-module-contentstack, @friggframework/api-module-crossbeam, @friggframework/api-module-deel, @friggframework/api-module-frigg-scale-test, @friggframework/api-module-frontify, @friggframework/api-module-google-calendar, @friggframework/api-module-google-drive, @friggframework/api-module-helpscout, @friggframework/api-module-hubspot, @friggframework/api-module-ironclad, @friggframework/api-module-linear, @friggframework/api-module-pipedrive, @friggframework/api-module-salesforce, @friggframework/api-module-stripe, @friggframework/api-module-unbabel-projects, @friggframework/api-module-unbabel, @friggframework/api-module-zoho-crm, @friggframework/api-module-zoom
    • feat(api): prevent calling setTokens on Zoho API error #76 (@d-klotz)

🐛 Bug Fix

  • @friggframework/api-module-hubspot
    • fix(hubspot): listContacts omits null after so it can paginate past page 1 #93 (@d-klotz)

Authors: 1

… page 1

listContacts always put `after` in the query string, defaulting it to null when no cursor was supplied. HubSpot's GET /crm/v3/objects/contacts rejects `after=null` (and `after=`) with a 400, so callers could never page past the first page — forcing them onto the search endpoint, which is hard-capped at 10,000 results and unusable for full-contact enumeration on large portals.

Only include `after` in the query once a cursor is actually present (second page onward). First-page calls now send just limit + properties. Adds unit tests for first page (no after), subsequent pages, and null after.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@d-klotz

d-klotz commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

🤖 Generated with Claude Code

@d-klotz d-klotz added the release label Jun 8, 2026
@d-klotz
d-klotz merged commit 1f763e4 into next Jun 8, 2026
4 checks passed
@d-klotz
d-klotz deleted the fix/hubspot-listcontacts-pagination branch June 8, 2026 15:18
@seanspeaks

Copy link
Copy Markdown
Contributor

🚀 PR was released in @friggframework/api-module-hubspot@2.0.0-next.6 🚀

@seanspeaks seanspeaks added the prerelease This change is available in a prerelease. label Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

prerelease This change is available in a prerelease. release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants