larksuite/cli · error

pagination exhausted its page budget without producing a ter

Error message

pagination exhausted its page budget without producing a terminal result

What it means

Walk pages through a cursor-based API and stops when it exhausts the configured page budget without receiving a terminal result; returning this error prevents infinite pagination loops against APIs that never terminate or always return a next cursor. It signals a budget/policy failure, not a network error.

Source

Thrown at internal/pagination/walk.go:122

			return state, &CursorError{Kind: CursorMissing, Page: pageNumber}
		}
		if _, duplicate := seen[nextToken]; duplicate {
			return state, &CursorError{Kind: CursorRepeated, Page: pageNumber, Token: nextToken}
		}
		state.NextToken = nextToken
		if pageNumber == options.MaxPages {
			return state, nil
		}
		seen[nextToken] = struct{}{}
		token = nextToken
		if options.Delay > 0 {
			if err := wait(ctx, options.Delay); err != nil {
				return state, &WaitError{Err: err}
			}
		}
	}

	return state, fmt.Errorf("pagination exhausted its page budget without producing a terminal result")
}

// WaitContext waits for one inter-page delay and observes cancellation.
func WaitContext(ctx context.Context, delay time.Duration) error {
	if delay <= 0 {
		return nil
	}
	timer := time.NewTimer(delay)
	defer timer.Stop()
	select {
	case <-ctx.Done():
		return ctx.Err()
	case <-timer.C:
		return nil
	}
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Increase the pagination page budget to cover the dataset size.
  2. Verify the API is actually advancing cursors — log page tokens; a repeating cursor indicates a server/bug issue.
  3. Resume from the last state's resume token in a follow-up Walk instead of doing it in one run.
  4. Check pagination/version behavior of the upstream API for known cursor loops.

Example fix

// before
state, err := pagination.Walk(ctx, opts) // budget too small
// after
opts.PageBudget = 10000 // sized to dataset
state, err := pagination.Walk(ctx, opts)
if err != nil {
    // persist state.ResumeToken and continue later
}
Defensive patterns

Strategy: validation

Validate before calling

if expectedPages > opts.PageBudget {
    return errors.New("dataset larger than pagination budget; raise PageBudget or use resume token")
}

Prevention

When it happens

Trigger: Calling Walk with a page budget (max pages) that is fully consumed while the API keeps returning a resume/cursor with no terminal state — e.g. too-small budget for a large dataset, or a server returning the same cursor repeatedly.

Common situations: Listing a dataset far larger than the default page budget; a misbehaving/stale API that keeps returning a next cursor; resume-token loops after API version changes; Delay+ctx waits consuming the walk window.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/0b016fa0609644f2. Report an issue: GitHub.