mastra-ai/mastra · error

page must be >= 0

Error message

page must be >= 0

What it means

Input validation in `list` of the in-memory MCP clients domain: pagination pages are zero-indexed, so a negative `page` argument is rejected before any query runs. It prevents computing a negative offset.

Source

Thrown at packages/core/src/storage/domains/mcp-clients/inmemory.ts:126

    return this.deepCopyConfig(updatedConfig);
  }

  async delete(id: string): Promise<void> {
    // Idempotent delete
    this.db.mcpClients.delete(id);
    // Also delete all versions for this client
    await this.deleteVersionsByParentId(id);
  }

  async list(args?: StorageListMCPClientsInput): Promise<StorageListMCPClientsOutput> {
    const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = 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 MCP clients and apply filters
    let configs = Array.from(this.db.mcpClients.values());

    // Filter by status
    if (status) {
      configs = configs.filter(config => config.status === status);
    }

    // Filter by authorId if provided
    if (authorId !== undefined) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Clamp page to 0 before calling: `page = Math.max(0, page)`.
  2. Fix previous-page logic to not go below the first page.
  3. Validate/normalize query-string pagination inputs at the API boundary.

Example fix

// before
const res = await mcpClients.list({ page: currentPage - 1 });
// after
const res = await mcpClients.list({ page: Math.max(0, currentPage - 1) });
Defensive patterns

Strategy: validation

Validate before calling

function assertValidPage(page: number): void {
  if (!Number.isInteger(page) || page < 0) throw new RangeError('page must be an integer >= 0');
}
assertValidPage(page);

Type guard

const isValidPage = (page: unknown): page is number =>
  typeof page === 'number' && Number.isInteger(page) && page >= 0;

Try / catch

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

Prevention

When it happens

Trigger: Calling `list({ page: -1 })` (or any negative value), often from a computed page number like `currentPage - 1` when already on page 0, or from deserialized request params.

Common situations: Off-by-one in 'previous page' UI logic; user-supplied query params parsed without clamping; migration from 1-indexed pagination APIs.

Related errors


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