{"record":{"id":"832c5b4aacc324b8","repo":"mastra-ai/mastra","slug":"perpage-must-be-false-or-a-safe-integer","errorCode":null,"errorMessage":"perPage must be false or a safe integer","messagePattern":"perPage must be false or a safe integer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/memory/base.ts","lineNumber":491,"sourceCode":"\n  /**\n   * Validates pagination input before normalization.\n   * Use this when accepting raw perPageInput (number | false) from callers.\n   *\n   * When perPage is false (fetch all), page must be 0 since pagination is disabled.\n   * When perPage is a number, delegates to validatePagination for full validation.\n   *\n   * @param page - Page number (0-indexed)\n   * @param perPageInput - Items per page as number, or false to fetch all results\n   * @throws Error if perPageInput is false and page !== 0\n   * @throws Error if perPageInput is invalid (not false or a non-negative safe integer)\n   * @throws Error if page is invalid or offset would overflow\n   */\n  protected validatePaginationInput(page: number, perPageInput: number | false): void {\n    // Validate perPageInput type first\n    if (perPageInput !== false) {\n      if (typeof perPageInput !== 'number' || !Number.isFinite(perPageInput) || !Number.isSafeInteger(perPageInput)) {\n        throw new Error('perPage must be false or a safe integer');\n      }\n      if (perPageInput < 0) {\n        throw new Error('perPage must be >= 0');\n      }\n    }\n\n    // When fetching all (perPage: false), only page 0 is valid\n    if (perPageInput === false) {\n      if (page !== 0) {\n        throw new Error('page must be 0 when perPage is false');\n      }\n      // Still validate page is a valid integer\n      if (!Number.isFinite(page) || !Number.isSafeInteger(page)) {\n        throw new Error('page must be >= 0');\n      }\n      return;\n    }\n","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/memory/base.ts#L473-L509","documentation":"validatePaginationInput accepts perPage as a number or the literal false (meaning 'fetch all'). If perPageInput is neither false nor a finite safe integer, this error is thrown. Strings, null, undefined, Infinity, and NaN are all rejected.","triggerScenarios":"Calling listThreads/listMessages with { perPage: '10' } (string from a query param), { perPage: null }, { perPage: undefined } typed as number, or { perPage: Infinity }.","commonSituations":"Passing unparsed query-string values (req.query always yields strings); JSON configs where perPage came through as null; TypeScript types bypassed via `as any` or JS callers.","solutions":["Parse and coerce: const perPage = raw === false ? false : Number.parseInt(raw, 10).","Validate with (perPage === false || (Number.isSafeInteger(perPage) && perPage >= 0)) before calling.","Use perPage: false explicitly (not null/undefined) when you want all records.","Enable strict TypeScript checking so string|null values cannot reach the call site."],"exampleFix":"// before\nawait storage.listThreads({ page: 0, perPage: req.query.perPage }); // string\n// after\nconst raw = req.query.perPage;\nconst perPage = raw === 'all' ? false : Math.max(0, parseInt(raw, 10) || 0);\nawait storage.listThreads({ page: 0, perPage });","handlingStrategy":"type-guard","validationCode":"function normalizePerPage(raw) {\n  if (raw === false) return false;\n  const n = Number(raw);\n  return Number.isSafeInteger(n) && n >= 0 ? n : 10;\n}","typeGuard":"function isValidPerPageInput(p: unknown): p is number | false {\n  return p === false || (typeof p === 'number' && Number.isSafeInteger(p) && p >= 0);\n}","tryCatchPattern":"try {\n  await storage.listThreads({ page: 0, perPage });\n} catch (e) {\n  if (e instanceof Error && e.message === 'perPage must be false or a safe integer') {\n    return storage.listThreads({ page: 0, perPage: 10 });\n  }\n  throw e;\n}","preventionTips":["Parse query params before passing perPage (they arrive as strings)","Use literal false, never null/undefined, for fetch-all","Enable strict TS so invalid types cannot reach the call"],"tags":["validation","pagination","types"],"backgroundTag":"invalid-pagination-parameters","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}