{"record":{"id":"ce739ff613b5e8e4","repo":"mastra-ai/mastra","slug":"page-value-too-large-ce739f","errorCode":null,"errorMessage":"page value too large","messagePattern":"page value too large","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/skills/inmemory.ts","lineNumber":235,"sourceCode":"      visibility,\n      metadata,\n      entityIds,\n      pinFavoritedFor,\n      favoritedOnly,\n    } = args || {};\n    const { field, direction } = this.parseOrderBy(orderBy);\n\n    // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 100)\n    const perPage = normalizePerPage(perPageInput, 100);\n\n    if (page < 0) {\n      throw new Error('page must be >= 0');\n    }\n\n    // Prevent unreasonably large page values\n    const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n    if (page * perPage > maxOffset) {\n      throw new Error('page value too large');\n    }\n\n    // Get all skills and apply filters\n    let configs = Array.from(this.db.skills.values());\n\n    // Restrict to a set of IDs (used by ?favoritedOnly=true).\n    // An empty array means \"no candidates\" -> empty result.\n    if (entityIds !== undefined) {\n      if (entityIds.length === 0) {\n        return {\n          skills: [],\n          total: 0,\n          page,\n          perPage: perPageInput === false ? false : perPage,\n          hasMore: false,\n        };\n      }\n      const idSet = new Set(entityIds);","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/skills/inmemory.ts#L217-L253","documentation":"The in-memory skills storage `list` method rejects a `page` argument whose resulting offset (`page * perPage`) exceeds `Number.MAX_SAFE_INTEGER / 2`. This guard prevents arithmetic that can no longer be represented exactly as a JS integer and is clearly a caller mistake rather than a storage state issue. The error fires during argument validation before any records are read.","triggerScenarios":"Calling `list({ page: <huge number> })` on the in-memory skills storage, where `page * perPage > 9007199254740991 / 2`. Typical sources are multiplying or overflowing a page counter, or passing an ID/string-cast number as page.","commonSituations":"Pagination cursors computed from data (e.g. using record IDs or timestamps as page numbers), off-by-scale bugs (paginating by milliseconds or bytes instead of pages), or client-supplied query params cast from user input without bounds checking.","solutions":["Check the computed page value at the call site; it should be a small sequential index starting at 0.","Fix any computation that derives `page` from IDs, timestamps, or byte offsets instead of record counts.","Clamp or validate user-supplied page params against a sane maximum before passing to storage.","If you truly need all records, pass `perPage: false` (normalizePerPage maps it to MAX_SAFE_INTEGER) with page 0 instead of a giant page number."],"exampleFix":"// before\nconst page = Number(req.query.page); // e.g. 1e15\nawait skills.list({ page });\n// after\nconst page = Math.max(0, parseInt(req.query.page, 10) || 0);\nif (page > 1e6) throw new BadRequestError('page out of range');\nawait skills.list({ page });","handlingStrategy":"validation","validationCode":"const MAX_OFFSET = Number.MAX_SAFE_INTEGER / 2;\nfunction assertValidPage(page: number, perPage: number) {\n  if (!Number.isInteger(page) || page < 0) throw new RangeError('page must be a non-negative integer');\n  if (page * perPage > MAX_OFFSET) throw new RangeError('page value too large');\n}","typeGuard":"function isSafePage(page: unknown): page is number {\n  return typeof page === 'number' && Number.isInteger(page) && page >= 0 && page * 20 <= Number.MAX_SAFE_INTEGER / 2;\n}","tryCatchPattern":"try {\n  const result = await skills.list({ page });\n} catch (err) {\n  if (err instanceof Error && err.message === 'page value too large') {\n    page = 0; // reset to first page and surface a warning\n  } else throw err;\n}","preventionTips":["Always derive page from record counts, never from IDs or timestamps.","Clamp user-supplied page params to a sane maximum at the API boundary.","Use `perPage: false` with page 0 to fetch everything instead of huge page numbers."],"tags":["pagination","argument-validation","storage"],"backgroundTag":"pagination-page-out-of-range","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}