## TL;DR

The generated client looped over edges but never checked pageInfo.hasNextPage, so it either stopped early or looped forever. The fix is small: read hasNextPage after each page and pass endCursor as the after argument for the next one.

## Error

```text
client fetched page 1 repeatedly; total records returned never grew past the first page
```

## Steps

1. Add pageInfo { hasNextPage endCursor } to the query Expected: the response carries pagination state.
2. Loop while hasNextPage is true, passing after: endCursor Expected: each request advances the cursor.
3. Append each page's edges to the result list Expected: no duplicates, no missing records.
4. Break when hasNextPage is false Expected: the loop terminates with the full set.

## When to use

- The API follows the Relay connection spec
- The generated client paginates but never finishes

## When not to use

- The API uses offset pagination instead
- You need bidirectional paging (then also handle hasPreviousPage)

## Tool compatibility

- GraphQL Relay connection spec
- Generated GraphQL clients

## Variant phrasings

### graphql pagination never ends

Check pageInfo.hasNextPage and advance with endCursor.

### only first page of graphql results

You are probably ignoring pageInfo. Request it and loop on hasNextPage.

## Why it happens

Agents pattern-match pagination as 'fetch edges in a loop' and skip the pageInfo block because examples often omit it for brevity.

## Edge cases

- Some servers return hasNextPage: true with an empty edges list on the last page; guard the loop
- Cursor stability matters if the underlying list changes mid-walk

## Provenance

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