## TL;DR

HubSpot search cursors can reset (results shift as the index updates), sending your pager back to the start or into a loop. Detect repeated cursors or repeated records, restart the search with a stable sort, and dedupe by id. Cursor resets are normal; looping forever is not.

## Error

```text
(No error; the symptom is the pager returning records it already returned, or the result set restarting.)
```

## Steps

1. Track seen record ids during paging. Expected: you detect repeats immediately.
2. On repeat detection, stop and restart the search with an explicit stable sort. Expected: deterministic ordering.
3. Dedupe the combined results by id. Expected: each record processed once.
4. If resets persist, narrow the search (tighter filters, smaller time windows) so each search completes before the index shifts. Expected: stable result sets.
5. For full extracts, prefer the list or export APIs over search paging. Expected: no cursor semantics at all.

## When to use

- Search paging loops or restarts.
- An agent pages search results and never finishes.
- Result counts that change between pages.

## When not to use

- List endpoint pagination (different cursor behavior).
- 429s during paging (rate limits).

## Tool compatibility

- HubSpot CRM search API v3 with after cursors.
- Seen-id tracking in the agent.

## Variant phrasings

### search cursor reset

Restart with stable sort; dedupe.

### paging returns duplicates

Same detection, same fix.

## Why it happens

Search runs against a live index that updates as you page. Inserts and updates shift result positions, invalidating the cursor's place. The API resets rather than serve wrong pages.

## Edge cases

- Sorting by last-modified makes resets more likely; sort by id or created date.
- Very large result sets reset more often; keep searches narrow.
- The after cursor from a reset response may itself be stale; restart clean.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_WHcZcQbKDlakFsE08v0Alg
