mastra-ai/mastra · error
page must be >= 0
Error message
page must be >= 0
What it means
validatePagination rejects a page argument that is negative, non-finite, or not a safe integer. Page numbers are 0-indexed in Mastra storage, so page must be an integer >= 0. This prevents undefined offset arithmetic in the storage layer.
Source
Thrown at packages/core/src/storage/domains/memory/base.ts:454
);
}
// Also limit key length to prevent potential issues
if (key.length > MAX_METADATA_KEY_LENGTH) {
throw new Error(`Metadata key "${key}" exceeds maximum length of ${MAX_METADATA_KEY_LENGTH} characters.`);
}
}
}
/**
* Validates pagination parameters and returns safe offset.
* @param page - Page number (0-indexed)
* @param perPage - Items per page (0 is allowed and returns empty results)
* @throws Error if page is negative, perPage is negative/invalid, or offset would overflow
*/
protected validatePagination(page: number, perPage: number): void {
if (!Number.isFinite(page) || !Number.isSafeInteger(page) || page < 0) {
throw new Error('page must be >= 0');
}
// perPage: 0 is allowed (returns empty results), negative values are rejected
if (!Number.isFinite(perPage) || !Number.isSafeInteger(perPage) || perPage < 0) {
throw new Error('perPage must be >= 0');
}
// Skip overflow check when perPage is 0 (no offset needed)
if (perPage === 0) {
return;
}
// Prevent overflow when calculating offset
const offset = page * perPage;
if (!Number.isSafeInteger(offset) || offset > Number.MAX_SAFE_INTEGER) {
throw new Error('page value too large');
}
}View on GitHub (pinned to 75dd419e61)
Solutions
- Clamp page to Math.max(0, Math.floor(Number(page))) before calling the storage API.
- Default page to 0 when the input is missing, NaN, or negative.
- Validate page with Number.isSafeInteger(page) && page >= 0 before the call.
- Fix 1-indexed UI code to subtract 1 before passing page to Mastra storage.
Example fix
// before
const { page = 1 } = req.query; // 1-indexed UI
await storage.listThreads({ page, perPage: 10 });
// after
const page = Math.max(0, Math.floor(Number(req.query.page ?? 1)) - 1);
await storage.listThreads({ page, perPage: 10 }); Defensive patterns
Strategy: validation
Validate before calling
function safePage(raw) {
const n = Number(raw);
return Number.isSafeInteger(n) && n >= 0 ? n : 0;
} Type guard
function isValidPage(p: unknown): p is number {
return typeof p === 'number' && Number.isSafeInteger(p) && p >= 0;
} Try / catch
try {
await storage.listThreads({ page: safePage(rawPage), perPage });
} catch (e) {
if (e instanceof Error && e.message === 'page must be >= 0') {
return storage.listThreads({ page: 0, perPage });
}
throw e;
} Prevention
- Always clamp user-supplied page values
- Remember pages are 0-indexed in Mastra storage
- Never pass raw query strings as page
When it happens
Trigger: Calling listThreads/listMessages with { page: -1 }, { page: NaN }, { page: 1.5 }, or { page: Infinity }; passing user-controlled pagination straight through without clamping.
Common situations: UI pagination math producing -1 when the user is on the first page and clicks 'previous'; parsing query params where '' or undefined coerces to NaN; off-by-one in 1-indexed vs 0-indexed page handling.
Related errors
- perPage must be >= 0
- page must be >= 0
- page value too large
- Invalid knowledge node cursor.
- page must be >= 0
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/e45ff949c3db4910.
Report an issue: GitHub.