{"record":{"id":"8c059b083775a442","repo":"mastra-ai/mastra","slug":"threadid-must-be-a-non-empty-string-or-array-of-no","errorCode":null,"errorMessage":"threadId must be a non-empty string or array of non-empty strings","messagePattern":"threadId must be a non-empty string or array of non-empty strings","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/memory/inmemory.ts","lineNumber":122,"sourceCode":"      }\n    });\n  }\n\n  async listMessages({\n    threadId,\n    resourceId: optionalResourceId,\n    include,\n    filter,\n    perPage: perPageInput,\n    page = 0,\n    orderBy,\n  }: StorageListMessagesInput): Promise<StorageListMessagesOutput> {\n    const metadataFilter = validateStorageMetadataFilter(filter?.metadata);\n    // Normalize threadId to array\n    const threadIds = Array.isArray(threadId) ? threadId : [threadId];\n\n    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    }","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/memory/inmemory.ts#L104-L140","documentation":"InMemoryStorage.listMessages requires threadId to be either a non-empty string or an array of non-empty strings (after trimming whitespace). The method normalizes a single threadId into an array and then validates that the array is non-empty and every element is non-blank. This guard prevents querying messages with an undefined/empty thread set, which would otherwise be ambiguous or accidentally match nothing/all threads.","triggerScenarios":"Calling listMessages({ threadId: '' }), threadId: undefined/null (bypassing types), threadId: [], or an array containing blank entries like ['thread-1', '   '] (whitespace-only strings pass a naive check but fail trim()).","commonSituations":"Thread ID sourced from an uninitialized variable, a route param that is an empty string before the record loads, React effects firing before thread creation completes, or JS callers (no TypeScript) passing null/undefined.","solutions":["Ensure a valid thread exists and its id is loaded before calling listMessages.","Filter out blank entries before passing an array: ids.filter(id => typeof id === 'string' && id.trim().length > 0), then skip the call if the result is empty.","If threadId may legitimately be absent, guard the call site rather than passing an empty value."],"exampleFix":"// before\nawait storage.listMessages({ threadId: thread?.id });\n// after\nif (thread?.id) {\n  await storage.listMessages({ threadId: thread.id });\n}","handlingStrategy":"validation","validationCode":"function hasValidThreadIds(threadId) {\n  const ids = Array.isArray(threadId) ? threadId : [threadId];\n  return ids.length > 0 && ids.every(id => typeof id === 'string' && id.trim().length > 0);\n}\nif (!hasValidThreadIds(threadId)) return; // skip call or surface input error\nawait storage.listMessages({ threadId });","typeGuard":"function isValidThreadId(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0;\n}\nfunction areValidThreadIds(v: unknown): v is string[] {\n  return Array.isArray(v) && v.length > 0 && v.every(isValidThreadId);\n}","tryCatchPattern":null,"preventionTips":["Never call listMessages before the thread id is resolved; gate on loaded state.","Filter blank strings from any array of ids derived from user input.","Rely on TypeScript types, but still validate at runtime when ids come from external sources (URLs, forms)."],"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"}