{"record":{"id":"be449340d88b4513","repo":"mastra-ai/mastra","slug":"page-value-too-large-be4493","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/memory/inmemory.ts","lineNumber":139,"sourceCode":"    if (threadIds.length === 0 || threadIds.some(id => !id.trim())) {\n      throw new Error('threadId must be a non-empty string or array of non-empty strings');\n    }\n\n    const threadIdSet = new Set(threadIds);\n\n    const { field, direction } = this.parseOrderBy(orderBy, 'ASC');\n\n    // Normalize perPage for query (false → MAX_SAFE_INTEGER, 0 → 0, undefined → 40)\n    const perPage = normalizePerPage(perPageInput, 40);\n\n    if (page < 0) {\n      throw new Error('page must be >= 0');\n    }\n\n    // Prevent unreasonably large page values that could cause performance issues\n    const maxOffset = Number.MAX_SAFE_INTEGER / 2;\n    if (page * perPage > maxOffset) {\n      throw new Error('page value too large');\n    }\n\n    // Calculate offset from page\n    const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);\n\n    // When perPage is 0 with no includes, there's nothing to return.\n    if (perPage === 0 && (!include || include.length === 0)) {\n      return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };\n    }\n\n    // Step 1: Get messages matching threadId(s) and optionally resourceId\n    let threadMessages = Array.from(this.db.messages.values()).filter((msg: any) => {\n      // Message must be in one of the specified threads\n      if (threadIdSet && !threadIdSet.has(msg.thread_id)) return false;\n      // If optionalResourceId provided, message must match it\n      if (optionalResourceId && msg.resourceId !== optionalResourceId) return false;\n      return true;\n    });","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/memory/inmemory.ts#L121-L157","documentation":"listMessages rejects page values whose computed offset (page * perPage) exceeds Number.MAX_SAFE_INTEGER / 2, because such offsets would break integer precision and cause severe performance issues in an in-memory store. The limit protects against astronomically large page numbers rather than normal pagination ranges.","triggerScenarios":"Calling listMessages with an absurd page number (e.g. page: Number.MAX_SAFE_INTEGER or a DoS-style crafted query param) combined with any perPage, such that page * perPage > MAX_SAFE_INTEGER / 2.","commonSituations":"Unvalidated API/query-string input forwarded straight to storage; attacker-supplied pagination params; tests probing boundary conditions.","solutions":["Clamp page to a sane upper bound for your application (e.g. page < 1_000_000) before calling.","Sanitize external pagination input: reject non-finite numbers and cap the value at the API boundary.","Prefer cursor/keyset pagination for very deep datasets instead of huge page offsets."],"exampleFix":"// before\nawait storage.listMessages({ threadId, page: Number(req.query.page) });\n// after\nconst page = Math.min(Math.max(0, Number(req.query.page) || 0), 1_000_000);\nawait storage.listMessages({ threadId, page });","handlingStrategy":"validation","validationCode":"const MAX_PAGE = 1_000_000;\nconst page = Math.min(Math.max(0, Number(rawPage) || 0), MAX_PAGE);\nawait storage.listMessages({ threadId, page });","typeGuard":"function isSafePage(v: unknown): v is number {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 0 && v <= 1_000_000;\n}","tryCatchPattern":null,"preventionTips":["Cap externally supplied page numbers at an application-defined maximum.","Reject non-finite input (Infinity, NaN) before arithmetic on page/perPage.","Use keyset/cursor pagination for deep scans instead of huge offsets."],"tags":["validation","pagination","storage","argument-error"],"backgroundTag":"invalid-pagination-args","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}