mastra-ai/mastra · error

page must be >= 0

Error message

page must be >= 0

What it means

The in-memory skills list() validates that page is a non-negative integer-like value before computing offsets; negative pages are meaningless in this 0-indexed pagination scheme and are rejected with this error.

Source

Thrown at packages/core/src/storage/domains/skills/inmemory.ts:229

    const {
      page = 0,
      perPage: perPageInput,
      orderBy,
      authorId,
      status,
      visibility,
      metadata,
      entityIds,
      pinFavoritedFor,
      favoritedOnly,
    } = args || {};
    const { field, direction } = this.parseOrderBy(orderBy);

    // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)
    const perPage = normalizePerPage(perPageInput, 100);

    if (page < 0) {
      throw new Error('page must be >= 0');
    }

    // Prevent unreasonably large page values
    const maxOffset = Number.MAX_SAFE_INTEGER / 2;
    if (page * perPage > maxOffset) {
      throw new Error('page value too large');
    }

    // Get all skills and apply filters
    let configs = Array.from(this.db.skills.values());

    // Restrict to a set of IDs (used by ?favoritedOnly=true).
    // An empty array means "no candidates" -> empty result.
    if (entityIds !== undefined) {
      if (entityIds.length === 0) {
        return {
          skills: [],
          total: 0,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Clamp: const safePage = Math.max(0, page) before calling list.
  2. Validate incoming page parameters (schema validation, e.g. z.number().int().min(0)).
  3. Convert 1-based client pages to 0-based with a guard for the first page.
  4. Pass false as perPageInput if the intent was 'return everything' rather than navigating pages.

Example fix

// before
const { skills } = await skillsStorage.list(orderBy, Number(req.query.page), 100);
// after
const safePage = Math.max(0, parseInt(String(req.query.page ?? '0'), 10) || 0);
const { skills } = await skillsStorage.list(orderBy, safePage, 100);
Defensive patterns

Strategy: validation

Validate before calling

function normalizePage(page: unknown): number {
  const n = typeof page === 'number' ? page : parseInt(String(page ?? '0'), 10);
  return Number.isFinite(n) && n > 0 ? Math.floor(n) : 0;
}

Type guard

function isNonNegativeInt(v: unknown): v is number {
  return typeof v === 'number' && Number.isInteger(v) && v >= 0;
}

Try / catch

try {
  return await storage.list(orderBy, page, perPage);
} catch (e) {
  if (e instanceof Error && e.message === 'page must be >= 0') {
    return storage.list(orderBy, 0, perPage);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling list(orderBy, -1, perPage) — e.g. a caller decrementing a 1-based page below 0, or propagating an unvalidated page from an HTTP query string (?page=-1).

Common situations: Off-by-one errors in pagination UI state; server handlers passing req.query.page straight through; defaulting logic that computes page = total - n producing negatives.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/79094bcf2f8bcfb9. Report an issue: GitHub.